blob: 2bdbee5551fc7d2fff831d9fb035f175b0be4a1f [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.documentsui;
import static com.android.documentsui.base.Shared.LAUNCHER_TARGET_CLASS;
import static com.android.documentsui.base.SharedMinimal.DEBUG;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.om.OverlayInfo;
import android.content.om.OverlayManager;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.util.Log;
import com.android.documentsui.theme.ThemeOverlayManager;
import com.android.documentsui.util.VersionUtils;
/**
* A receiver listening action.PRE_BOOT_COMPLETED event for setting component enable or disable.
* Since there's limitation of overlay AndroidManifest.xml attrs at boot stage.
* The workaround to retrieve config from DocumentsUI RRO package at boot time in Q.
*/
public class PreBootReceiver extends BroadcastReceiver {
private static final String TAG = "PreBootReceiver";
private static final String CONFIG_IS_LAUNCHER_ENABLED = "is_launcher_enabled";
private static final String CONFIG_HANDLE_VIEW_DOWNLOADS = "handle_view_downloads_intent";
private static final String DOWNLOADS_TARGET_CLASS =
"com.android.documentsui.ViewDownloadsActivity";
@SuppressLint("NewApi") // OverlayManager is @hdie
@Override
public void onReceive(Context context, Intent intent) {
final PackageManager pm = context.getPackageManager();
if (pm == null) {
Log.w(TAG, "Can't obtain PackageManager from System Service!");
return;
}
final OverlayManager om = context.getSystemService(OverlayManager.class);
if (om == null) {
Log.w(TAG, "Can't obtain OverlayManager from System Service!");
return;
}
final OverlayInfo info = new ThemeOverlayManager(om,
context.getPackageName()).getValidOverlay(pm);
if (info == null) {
Log.w(TAG, "Can't get valid overlay info");
return;
}
final String overlayPkg = info.getPackageName();
final String packageName = context.getPackageName();
Resources overlayRes;
try {
overlayRes = pm.getResourcesForApplication(overlayPkg);
} catch (PackageManager.NameNotFoundException e) {
Log.w(TAG, "Failed while parse package res.");
overlayRes = null;
}
if (overlayRes == null) {
return;
}
setComponentEnabledByConfigResources(pm, packageName, LAUNCHER_TARGET_CLASS,
overlayPkg, overlayRes, CONFIG_IS_LAUNCHER_ENABLED);
setComponentEnabledByConfigResources(pm, packageName, DOWNLOADS_TARGET_CLASS,
overlayPkg, overlayRes, CONFIG_HANDLE_VIEW_DOWNLOADS);
}
private static void setComponentEnabledByConfigResources(PackageManager pm, String packageName,
String className, String overlayPkg, Resources overlayRes, String config) {
int resId = overlayRes.getIdentifier(config, "bool", overlayPkg);
if (resId != 0) {
final ComponentName component = new ComponentName(packageName, className);
boolean enabled = overlayRes.getBoolean(resId);
if (VersionUtils.isAtLeastS() && CONFIG_IS_LAUNCHER_ENABLED.equals(config)) {
enabled = false; // Do not allow LauncherActivity to be enabled for S+.
}
if (DEBUG) {
Log.i(TAG,
"Overlay package:" + overlayPkg + ", customize " + config + ":" + enabled);
}
pm.setComponentEnabledSetting(component, enabled
? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
}
}