blob: 7304f0788a1dba34d8b780e436a070bdf0716e3e [file] [log] [blame]
Dongwon Kang569da9f2017-11-06 09:53:52 -08001/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.media;
18
Dongwon Kang569da9f2017-11-06 09:53:52 -080019import android.content.BroadcastReceiver;
Dongwon Kanged187722018-02-27 17:25:37 -080020import android.content.Context;
Dongwon Kang569da9f2017-11-06 09:53:52 -080021import android.content.Intent;
22import android.content.IntentFilter;
23import android.content.pm.ApplicationInfo;
24import android.content.pm.PackageManager;
Chong Zhang61211382018-09-19 17:13:56 -070025import android.media.IMediaUpdateService;
Dongwon Kang4a649362018-03-09 17:24:08 -080026import android.os.Build;
Dongwon Kang569da9f2017-11-06 09:53:52 -080027import android.os.IBinder;
Dongwon Kanged187722018-02-27 17:25:37 -080028import android.os.Handler;
Dongwon Kang569da9f2017-11-06 09:53:52 -080029import android.os.PatternMatcher;
30import android.os.ServiceManager;
Dongwon Kang4a649362018-03-09 17:24:08 -080031import android.os.SystemProperties;
Dongwon Kanged187722018-02-27 17:25:37 -080032import android.os.UserHandle;
Dongwon Kang4a649362018-03-09 17:24:08 -080033import android.text.TextUtils;
Dongwon Kanged187722018-02-27 17:25:37 -080034import android.util.Log;
35import android.util.Slog;
36import com.android.server.SystemService;
Chong Zhang61211382018-09-19 17:13:56 -070037import java.util.HashMap;
Dongwon Kang569da9f2017-11-06 09:53:52 -080038
39/** This class provides a system service that manages media framework updates. */
40public class MediaUpdateService extends SystemService {
41 private static final String TAG = "MediaUpdateService";
42 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
Dongwon Kang4a649362018-03-09 17:24:08 -080043 private static final String MEDIA_UPDATE_PACKAGE_NAME =
44 SystemProperties.get("ro.mediacomponents.package");
Dongwon Kang569da9f2017-11-06 09:53:52 -080045 private static final String EXTRACTOR_UPDATE_SERVICE_NAME = "media.extractor.update";
Chong Zhang61211382018-09-19 17:13:56 -070046 private static final String CODEC_UPDATE_SERVICE_NAME = "media.codec.update";
47 private static final String[] UPDATE_SERVICE_NAME_ARRAY = {
48 EXTRACTOR_UPDATE_SERVICE_NAME, CODEC_UPDATE_SERVICE_NAME,
49 };
50 private final HashMap<String, IMediaUpdateService> mUpdateServiceMap = new HashMap<>();
51 private final Handler mHandler = new Handler();
Dongwon Kang569da9f2017-11-06 09:53:52 -080052
53 public MediaUpdateService(Context context) {
54 super(context);
55 }
56
57 @Override
58 public void onStart() {
Dongwon Kang4a649362018-03-09 17:24:08 -080059 if (("userdebug".equals(android.os.Build.TYPE) || "eng".equals(android.os.Build.TYPE))
60 && !TextUtils.isEmpty(MEDIA_UPDATE_PACKAGE_NAME)) {
Chong Zhang61211382018-09-19 17:13:56 -070061 for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
62 connect(serviceName);
63 }
Dongwon Kange6c56132018-01-16 18:14:37 -080064 registerBroadcastReceiver();
65 }
Dongwon Kang569da9f2017-11-06 09:53:52 -080066 }
67
Chong Zhang61211382018-09-19 17:13:56 -070068 private void connect(final String serviceName) {
69 IBinder binder = ServiceManager.getService(serviceName);
Dongwon Kang569da9f2017-11-06 09:53:52 -080070 if (binder != null) {
71 try {
72 binder.linkToDeath(new IBinder.DeathRecipient() {
73 @Override
74 public void binderDied() {
Chong Zhang61211382018-09-19 17:13:56 -070075 Slog.w(TAG, "service " + serviceName + " died; reconnecting");
76 synchronized (mUpdateServiceMap) {
77 mUpdateServiceMap.remove(serviceName);
78 }
79 connect(serviceName);
Dongwon Kang569da9f2017-11-06 09:53:52 -080080 }
81 }, 0);
82 } catch (Exception e) {
83 binder = null;
84 }
85 }
86 if (binder != null) {
Chong Zhang61211382018-09-19 17:13:56 -070087 synchronized (mUpdateServiceMap) {
88 mUpdateServiceMap.put(serviceName,
89 IMediaUpdateService.Stub.asInterface(binder));
90 }
Dongwon Kanged187722018-02-27 17:25:37 -080091 mHandler.post(new Runnable() {
92 @Override
93 public void run() {
Chong Zhang61211382018-09-19 17:13:56 -070094 packageStateChanged(serviceName);
Dongwon Kanged187722018-02-27 17:25:37 -080095 }
96 });
Dongwon Kang569da9f2017-11-06 09:53:52 -080097 } else {
Chong Zhang61211382018-09-19 17:13:56 -070098 Slog.w(TAG, serviceName + " not found.");
Dongwon Kang569da9f2017-11-06 09:53:52 -080099 }
100 }
101
102 private void registerBroadcastReceiver() {
103 BroadcastReceiver updateReceiver = new BroadcastReceiver() {
104 @Override
105 public void onReceive(Context context, Intent intent) {
106 if (intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_SYSTEM)
107 != UserHandle.USER_SYSTEM) {
108 // Ignore broadcast for non system users. We don't want to update system
109 // service multiple times.
110 return;
111 }
112 switch (intent.getAction()) {
113 case Intent.ACTION_PACKAGE_REMOVED:
114 if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) {
115 // The existing package is updated. Will be handled with the
116 // following ACTION_PACKAGE_ADDED case.
117 return;
118 }
Chong Zhang61211382018-09-19 17:13:56 -0700119 // fall-thru
Dongwon Kang569da9f2017-11-06 09:53:52 -0800120 case Intent.ACTION_PACKAGE_CHANGED:
Dongwon Kang569da9f2017-11-06 09:53:52 -0800121 case Intent.ACTION_PACKAGE_ADDED:
Chong Zhang61211382018-09-19 17:13:56 -0700122 for (String serviceName : UPDATE_SERVICE_NAME_ARRAY) {
123 packageStateChanged(serviceName);
124 }
Dongwon Kang569da9f2017-11-06 09:53:52 -0800125 break;
126 }
127 }
128 };
129 IntentFilter filter = new IntentFilter();
130 filter.addAction(Intent.ACTION_PACKAGE_ADDED);
131 filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
132 filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
133 filter.addDataScheme("package");
134 filter.addDataSchemeSpecificPart(MEDIA_UPDATE_PACKAGE_NAME, PatternMatcher.PATTERN_LITERAL);
135
136 getContext().registerReceiverAsUser(updateReceiver, UserHandle.ALL, filter,
137 null /* broadcast permission */, null /* handler */);
138 }
139
Chong Zhang61211382018-09-19 17:13:56 -0700140 private void packageStateChanged(String serviceName) {
Dongwon Kang569da9f2017-11-06 09:53:52 -0800141 ApplicationInfo packageInfo = null;
142 boolean pluginsAvailable = false;
143 try {
144 packageInfo = getContext().getPackageManager().getApplicationInfo(
145 MEDIA_UPDATE_PACKAGE_NAME, PackageManager.MATCH_SYSTEM_ONLY);
146 pluginsAvailable = packageInfo.enabled;
147 } catch (Exception e) {
148 Slog.v(TAG, "package '" + MEDIA_UPDATE_PACKAGE_NAME + "' not installed");
149 }
Dongwon Kang4a649362018-03-09 17:24:08 -0800150 if (packageInfo != null && Build.VERSION.SDK_INT != packageInfo.targetSdkVersion) {
151 Slog.w(TAG, "This update package is not for this platform version. Ignoring. "
152 + "platform:" + Build.VERSION.SDK_INT
153 + " targetSdk:" + packageInfo.targetSdkVersion);
154 pluginsAvailable = false;
155 }
Chong Zhang61211382018-09-19 17:13:56 -0700156 loadPlugins(serviceName,
Dongwon Kang569da9f2017-11-06 09:53:52 -0800157 (packageInfo != null && pluginsAvailable) ? packageInfo.sourceDir : "");
158 }
159
Chong Zhang61211382018-09-19 17:13:56 -0700160 private void loadPlugins(String serviceName, String apkPath) {
Dongwon Kang569da9f2017-11-06 09:53:52 -0800161 try {
Chong Zhang61211382018-09-19 17:13:56 -0700162 IMediaUpdateService service = null;
163 synchronized (serviceName) {
164 service = mUpdateServiceMap.get(serviceName);
165 }
166 if (service != null) {
167 service.loadPlugins(apkPath);
168 } else {
169 Slog.w(TAG, "service " + serviceName + " passed away");
Dongwon Kang569da9f2017-11-06 09:53:52 -0800170 }
171 } catch (Exception e) {
Chong Zhang61211382018-09-19 17:13:56 -0700172 Slog.w(TAG, "Error in loadPlugins for " + serviceName, e);
Dongwon Kang569da9f2017-11-06 09:53:52 -0800173 }
174 }
175}