| /* |
| * 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); |
| } |
| } |
| } |