Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cdd434dc authored by Aaron Kling's avatar Aaron Kling Committed by Jan Altensen
Browse files

Add nvidia profile manager



This implements and API for apps to interface with NvCPL and by
extension the PowerHAL.

Reverse engineered from the Shield Experience 9.1.1 update then cleaned
up to match Android standards.

Co-authored-by: default avatarnift4 <nift4@protonmail.com>

Change-Id: I774ac62c8867151f21712cfeee25f96a591415ad
(cherry picked from commit e5b84fdd)
parent 20e0c5d2
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.UserIcons;

import com.nvidia.NvAppProfileService;

import dalvik.system.VMRuntime;

import libcore.util.EmptyArray;
@@ -171,6 +173,7 @@ public class ApplicationPackageManager extends PackageManager {
    private volatile UserManager mUserManager;
    private volatile PermissionManager mPermissionManager;
    private volatile PackageInstaller mInstaller;
    private volatile NvAppProfileService mAppProfileService;
    private volatile ArtManager mArtManager;
    private volatile DevicePolicyManager mDevicePolicyManager;
    private volatile String mPermissionsControllerPackageName;
@@ -478,6 +481,15 @@ public class ApplicationPackageManager extends PackageManager {
                com.android.internal.R.bool.config_wirelessConsentRequired);
    }

    /** @hide */
    @Override
    public NvAppProfileService getAppProfileService() {
        if (mAppProfileService == null) {
            mAppProfileService = new NvAppProfileService(mContext);
        }
        return mAppProfileService;
    }

    @Override
    public ApplicationInfo getApplicationInfo(String packageName, int flags)
            throws NameNotFoundException {
+7 −0
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.DataClass;

import com.nvidia.NvAppProfileService;

import dalvik.system.VMRuntime;

import java.io.File;
@@ -5706,6 +5708,11 @@ public abstract class PackageManager {
    public abstract List<PermissionGroupInfo> getAllPermissionGroups(
            @PermissionGroupInfoFlags int flags);

    /** @hide */
    public NvAppProfileService getAppProfileService() {
        return null;
    }

    /**
     * Get the platform-defined permissions which belong to a particular permission group.
     *
+263 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 2012 - 2014 NVIDIA Corporation.  All rights reserved.
 *
 * 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.
 *
 * Class structure based upon Camera in Camera.java:
 * Copyright (C) 2009 The Android Open Source Project
 */

package com.nvidia;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.text.TextUtils;
import android.util.Log;

import com.nvidia.profilemanager.NvAppProfileSettingId;

import java.util.Arrays;
import java.util.List;

/**
 * @hide
 */
public class NvAppProfileService {
    private static final String TAG = "NvAppProfileService";
    private static final String APP_START_ACTION =
            "com.nvidia.NvAppProfileService.action.APP_START";
    private static final String APP_START_TARGET_PACKAGE = "com.nvidia.stats";
    private static final String FEATURE_POWER_BUDGET_CONTROL =
            "nvidia.feature.power_budget_control";
    private static final String FEATURE_FAN_ON_DEVICE = "nvidia.feature.fan_on_device";
    private static final String NvPowerModeProperty = "persist.vendor.sys.NV_POWER_MODE";

    private final NvAppProfiles mAppProfile;
    private final Context mContext;

    private boolean mInitAppProfiles = false;
    private boolean mFanCapEnabled = false;
    private boolean mPbcEnabled = false;

    public NvAppProfileService(Context context) {
        Context appContext = context.getApplicationContext();
        if (appContext == null) {
            mContext = context;
        } else {
            mContext = appContext;
        }

        mAppProfile = new NvAppProfiles(mContext);
    }

    private static String getPackageName(String appName) {
        int index = appName.indexOf('/');
        if (index < 0) {
            Log.e(TAG, "appName does not contain '/'. " +
                    "The packageName cannot be extracted from appName!");
            return null;
        }
        return appName.substring(0, index);
    }

    /*
     * These are functions that depend on NvAppProfiles and may or may not
     * be supported for certain platforms. In the latter case, these methods
     * should return -1.
     */
    public boolean canForceHwUi(String appName) {
        if (appName == null) {
            return false;
        }

        String packageName = getPackageName(appName);
        if (packageName == null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.FORCE_HW_UI) <= 0) {
            return false;
        }

        return true;
    }

    public boolean getAppProfileFRCEnable(String packageName) {
        return packageName != null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.VIDEO_FRC_ENABLE) == 1;
    }

    public boolean getAppProfileCreateSecureDecoder(String packageName) {
        return packageName != null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.VIDEO_SECURE_DECODE) == 1;
    }

    public boolean getAppProfileTSFilterEnable(String packageName) {
        return packageName != null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.VIDEO_TS_FILTERING) == 1;
    }

    public boolean getAppProfileNvidiaCertification(String packageName) {
        return packageName != null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.NVIDIA_VIDEO_CERTIFICATION_ENABLED) == 1;
    }

    public boolean getAppProfileDisableApp(String packageName) {
        return packageName != null && mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.DISABLE_APP) == 1;
    }

    private int getAppProfileCpuScalingMinFreq(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.SCALING_MIN_FREQ);
    }

    private int getAppProfileCpuCoreBias(String packageName) {
        return mAppProfile.getApplicationProfile(packageName, NvAppProfileSettingId.CORE_BIAS);
    }

    private int getAppProfileGpuScaling(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.GPU_SCALING);
    }

    private int getAppProfileCpuMaxNormalFreq(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.CPU_FREQ_BIAS);
    }

    private int getAppProfileCpuMaxNormalFreqPercent(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.MAX_CPU_FREQ_PCT);
    }

    private int getAppProfileCpuMinCore(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.MIN_CPU_CORES);
    }

    private int getAppProfileCpuMaxCore(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.MAX_CPU_CORES);
    }

    private int getAppProfileGpuCbusCapLevel(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.GPU_CORE_CAP);
    }

    private int getAppProfileEdpMode(String packageName) {
        return mAppProfile.getApplicationProfile(packageName, NvAppProfileSettingId.EDP_MODE);
    }

    private int getAppProfilePbcPwr(String packageName) {
        if (!mPbcEnabled) return -1;

        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.PBC_PWR_LIMIT);
    }

    private int getAppProfileFanCap(String packageName) {
        if (!mFanCapEnabled) return -1;

        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.FAN_PWM_CAP);
    }

    private int getAppProfileVoltTempMode(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.VOLT_TEMP_MODE);
    }

    private int getAppProfileAggresivePrismEnable(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.AGGRESSIVE_PRISM_ENABLE);
    }

    private int getAppProfileDevicePowerMode(String packageName) {
        return mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.SYSTEM_POWER_MODE);
    }

    public String getAppProfileRegionEnableList(String packageName) {
        return mAppProfile.getApplicationProfileString(packageName,
                NvAppProfileSettingId.SET_REGION_LIST);
    }

    public int getAppProfileNvidiaBBCApps(String packageName) {
        return mAppProfile.getApplicationProfile(packageName, NvAppProfileSettingId.BBC_APPS);
    }

    public List<String> getAppProfileForceQueryAppList() {
        String applicationProfileString = mAppProfile.getApplicationProfileString(
                "com.nvidia.shield.force_query_app_list",
                NvAppProfileSettingId.FORCE_QUERY_PACKAGES);
        if (TextUtils.isEmpty(applicationProfileString)) {
            return null;
        }
        return Arrays.asList(applicationProfileString.split(";"));
    }

    public List<String> getAppProfileAutoMediaScanPackages() {
        String applicationProfileString = mAppProfile.getApplicationProfileString(
                "com.nvidia.shield.auto_media_scan_packages",
                NvAppProfileSettingId.AUTO_MEDIA_SCAN_PACKAGES);
        if (TextUtils.isEmpty(applicationProfileString)) {
            return null;
        }
        return Arrays.asList(applicationProfileString.split(";"));
    }

    private int retrievePowerMode() {
        final String powerMode = SystemProperties.get(NvPowerModeProperty);
        if (powerMode != null) {
            try {
                return Integer.parseInt(powerMode);
            } catch (NumberFormatException ex) {
                // Fallthrough to error case
            }
        }

        return -1;
    }

    private void setGpuModeSetting(String packageName) {
        mAppProfile.getApplicationProfile(packageName,
                NvAppProfileSettingId.GPU_MODESET_ENABLE);
    }

    /**
     * Interface for the caller
     */
    public void setAppProfile(String packageName) {
        // Greedy initialization of App Profiles
        if (!mInitAppProfiles) {
            PackageManager pm = mContext.getPackageManager();
            mPbcEnabled = pm.hasSystemFeature(FEATURE_POWER_BUDGET_CONTROL);
            mFanCapEnabled = pm.hasSystemFeature(FEATURE_FAN_ON_DEVICE);

            Log.w(TAG, "Enabled");
            mInitAppProfiles = true;
        }

        mAppProfile.powerHint(packageName);

        Intent intent = new Intent(APP_START_ACTION);
        intent.setPackage(APP_START_TARGET_PACKAGE);
        intent.putExtra("AppStartId", packageName);
        mContext.sendBroadcastAsUser(intent, UserHandle.CURRENT,
                "nvidia.permission.READ_APP_START_INFO");
    }
}
+77 −0
Original line number Diff line number Diff line
package com.nvidia;

import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;

import com.nvidia.NvCPLSvc.INvCPLRemoteService;

public class NvAppProfiles {
    /**
     * Unique name used for NvCPLSvc to whitelist this class
     */
    static final String NV_APP_PROFILES_NAME = "Frameworks_NvAppProfiles";
    static final boolean DEBUG = false;
    private static final String TAG = "NvAppProfiles";
    private final Context mContext;
    private INvCPLRemoteService mNvCPLSvc = null;

    /**
     * Callback class given by the NvCPLService
     */

    public NvAppProfiles(Context context) {
        mContext = context;
    }

    public int getApplicationProfile(String packageName, int settingId) {
        getNvCPLService();
        if (mNvCPLSvc != null) {
            try {
                return mNvCPLSvc.getAppProfileSettingInt(packageName, settingId);
            } catch (RemoteException ex) {
                Log.w(TAG, "Failed to retrieve profile setting. Error=" + ex.getMessage());
            }
        }

        return -1;
    }

    public String getApplicationProfileString(String packageName, int settingId) {
        getNvCPLService();
        if (mNvCPLSvc != null) {
            try {
                return mNvCPLSvc.getAppProfileSettingString(packageName, settingId);
            } catch (RemoteException ex) {
                Log.w(TAG, "Failed to retrieve profile setting. Error=" + ex.getMessage());
            }
        }

        return null;
    }

    public void powerHint(String packageName) {
        getNvCPLService();
        if (mNvCPLSvc != null) {
            try {
                mNvCPLSvc.powerHint(packageName);
            } catch (RemoteException ex) {
                Log.w(TAG, "Failed to send power hint. Error=" + ex.getMessage());
            }
        }
    }

    private void getNvCPLService() {
        if (mNvCPLSvc == null) {
            try {
                mNvCPLSvc = INvCPLRemoteService.Stub.asInterface(
                        ServiceManager.getService("nvcpl"));
            } catch (Exception e) {
                Log.e(TAG, "Failed to bind to service. " + e.getMessage());
            }
        }
    }
}
+66 −0
Original line number Diff line number Diff line
package com.nvidia.framework;

import java.util.Arrays;
import java.util.List;

public class NvConstants {
    public static final String ACTION_DUMP_SERVICE_REPORT = "com.android.ams.action.DUMP_REPORT";
    public static final String ACTION_TV_LAUNCHER_LAUNCH = "com.android.ams.action.TV_LAUNCHER_LAUNCH";
    public static final String ALEXA_ACTION_ALEXA_OOBE_CANCELLED = "com.nvidia.shield.alexaexternal.action.ALEXA_OOBE_CANCELLED ";
    public static final String ALEXA_ACTION_ASSISTANT_APP_RESUMED = "com.nvidia.shield.alexaexternal.action.ASSISTANT_APP_RESUMED";
    public static final String ALEXA_ACTION_BOOT_COMPLETED = "com.nvidia.shield.alexaexternal.action.BOOT_COMPLETED";
    public static final String ALEXA_ACTION_CHANGE_MENU_BUTTON_ALEXA_SETTING = "com.nvidia.shield.alexaexternal.action.CHANGE_MENU_BUTTON_ALEXA_SETTING";
    public static final String ALEXA_ACTION_START_ALEXA_OOBE = "com.nvidia.shield.alexaexternal.action.START_ALEXA_OOBE";
    public static final String ALEXA_ACTION_START_EXTERNAL_SERVICE = "com.nvidia.shield.alexaexternal.action.START_EXTERNAL_SERVICE";
    public static final String ALEXA_ACTION_START_UTTERANCE = "com.nvidia.shield.alexaexternal.action.START_UTTERANCE";
    public static final String ALEXA_ASSISTANT_APP_ACTIVITY_NAME = "com.amazon.alexa.multimodal.LaunchActivity";
    public static final String ALEXA_ASSISTANT_APP_PACKAGE_NAME = "com.amazon.alexa.multimodal.nyla";
    public static final String ALEXA_EXTERNAL_APP_ACTIVITY_NAME = "com.nvidia.shield.alexaexternal.MainActivity";
    public static final String ALEXA_EXTERNAL_APP_PACKAGE_NAME = "com.nvidia.shield.alexaexternal";
    public static final String ALEXA_EXTERNAL_APP_SERVICE_NAME = "com.nvidia.shield.alexaexternal.AlexaExternalService";
    public static final int ALEXA_OOBE_STATE_CANCELLED = 2;
    public static final int ALEXA_OOBE_STATE_COMPLETE = 3;
    public static final int ALEXA_OOBE_STATE_HAS_NOT_STARTED = 0;
    public static final int ALEXA_OOBE_STATE_IN_PROGRESS = 1;
    public static final String EXTRA_MESSENGER_CB = "messenger_cb";
    public static final String EXTRA_REPORT_DATA = "service_report";
    public static final String INTENT_EXTRA_ALEXA_LAUNCH_METHOD = "LAUNCH_METHOD";
    public static final String INTENT_EXTRA_AUDIO_BUFFERING_STATE = "AUDIO_BUFFERING_STATE";
    public static final String METHOD_DEVICE_SETUP = "DEVICE_SETUP";
    public static final String METHOD_HOME_SCREEN = "HOME_SCREEN";
    public static final String METHOD_OTA_UPDATE = "OTA_UPDATE";
    public static final String METHOD_REMOTE_MENU = "REMOTE_MENU";
    public static final int NV_AUTOMATIC_POWER_MODE_DISABLED = -1;
    public static final String NV_BENCHMARK_APP_LAUNCH_INTENT = "com.nvidia.benchmarkblocker.APP_LAUNCH";
    public static final String NV_BENCHMARK_BLOCKER_CLASS_NAME = "com.nvidia.benchmarkblocker.NvBenchmarkBlockerService";
    public static final String NV_BENCHMARK_BLOCKER_PACKAGE_NAME = "com.nvidia.benchmarkblocker";
    public static final List<String> NV_DEFAULT_GAME_MODE_ENABLE_APPS = Arrays.asList("com.google.stadia.androidtv", "com.google.android.apps.tachyon", "com.gamepass");
    public static final int NV_MAX_BATTERY_LEVEL = 100;
    public static final int NV_POWER_MODE_BATTERY_SAVER = 2;
    public static final int NV_POWER_MODE_CUSTOM = 3;
    public static final int NV_POWER_MODE_INVALID = -1;
    public static final int NV_POWER_MODE_MAX_PERF = 0;
    public static final int NV_POWER_MODE_OPTIMIZED = 1;
    public static final String NvAppClose = "com.nvidia.app.close";
    public static final String NvBatteryMonitor = "com.nvidia.NvCPLSvc.BatteryMonitor";
    public static final String NvCPLService = "com.nvidia.NvCPLSvc.NvCPLService";
    public static final String NvCPLSvc = "com.nvidia.NvCPLSvc";
    public static final String NvMaxGpuMode = "com.nvidia.NvCPLSvc.MaxGpuMode";
    public static final String NvOrigin = "com.nvidia.NvCPLSvc.Origin";
    public static final String NvPowerMode = "com.nvidia.NvCPLSvc.NV_POWER_MODE";
    public static final String NvPowerModeProperty = "persist.vendor.sys.NV_POWER_MODE";
    public static final String NvStateId = "com.nvidia.NvCPLSvc.StateID";
    public static final String NvTCPDivisor = "com.nvidia.NvCPLSvc.NV_TCPDIVISOR";
    public static final String NvThermalStats = "com.nvidia.peripheralservice.NvThermalStats";
    public static final String PACKAGE_NAME_APPSELECTOR = "com.nvidia.shield.appselector";
    public static final String PACKAGE_NAME_TV_LAUNCHER = "com.google.android.tvlauncher";
    public static final int POWER_CUSTOM = 3;
    public static final int POWER_MAX_PERF = 0;
    public static final int POWER_OPTIMIZED = 1;
    public static final int POWER_SAVE_BATTERY = 2;
    public static final String PROPERTY_DISABLE_BUFFER_AGE = "debug.hwui.disable_buffer_age";
    public static final int WIFI_FREQUENCY_BAND_2GHZ = 2;
    public static final int WIFI_FREQUENCY_BAND_5GHZ = 1;
    public static final int WIFI_FREQUENCY_BAND_AUTO = 0;
    public static final int maxPerfMode = 0;
}
Loading