RK3568平台-定制系统服务(FrameWork)控制导航栏、状态栏、下拉框

671 阅读3分钟

前言

定制系统api,首先遵照着AIDL-Service-Manager-App的原则,每一步去实现,本次教程首先定义的系统API接口如下说明:

方法名(void)参数(String)参数(boolean)
setSystemBarShowtypevisibility

type

  • NavigationBar 底部导航栏
  • StatusBar 顶部状态栏
  • DrowDown 下拉框显示

visibility

  • true 显示
  • false 隐藏

IWSettingsService.aidl

创建新的AIDL文件

路径:framework/base/core/java/android/os/IWSettingsService.aidl

代码如下,按照上述定义的函数定义接口即可

package android.os; 
/** 
 * @hide 
*/ 
interface IWSettingsService 
{ 
    void setSystemBarShow(String type,boolean visibility); 
}

注意:必须用@hide注解,否则会编译失败

WSettingsService.java

创建对应aidl实现的是service实现的类

路径:framework/base/services/core/java/com/android/server/WSettingsService.java

根据AIDL的接口,我们采用的埋点的方式,通过广播的方式,将需要控制的信息传递给对应的类,这些对应的类的埋点位置,后续会介绍,大家注意的地方这里采用的是隐式广播的方式

package com.android.server;  
 
import android.content.Context;
import android.util.Slog;  
import android.os.IWSettingsService;
import android.content.Context;
import android.content.Intent;
import android.provider.Settings; 
 
public class WSettingsService extends IWSettingsService.Stub 
{ 
    private static final String TAG = "WSettingsService"; 
	
    private Context mContext;
	
    public WSettingsService(Context context) 
    {
	this.mContext = context;  
    }
	
    public void setSystemBarShow(String type,boolean visibility)
    {
	if(type.equals("NavigationBar"))
	{
            if(visibility)
            {
                showNavigationBar();
            }
            else
            {
                hideNavigationBar();
            }
	}
        else if(type.equals("StatusBar"))
        {
            if(visibility)
            {
                showStatusBar();
            }
            else
            {
                hideStatusBar();
            }
        }
        else if(type.equals("DropDown"))
        {
            if(visibility)
            {
                showDropDown();
            }
            else
            {
                hideDropDown();
            }
        }
    }
	
    private void hideNavigationBar()
    {
        // 隐藏导航栏
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_HIDE_NAVIGATION");
        mContext.sendBroadcast(intent);
    }
    
    private void showNavigationBar()
    {
        // 显示导航栏
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_SHOW_NAVIGATION");
        mContext.sendBroadcast(intent);
    }
    
    private void hideStatusBar()
    {
        // 隐藏状态栏
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_HIDE_STATUS_BAR");
        mContext.sendBroadcast(intent);
    }
    
    private void showStatusBar()
    {
        // 显示状态栏
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_SHOW_STATUS_BAR");
        mContext.sendBroadcast(intent);
    } 
    
    private void hideDropDown()
    {
        //禁止下拉框
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_HIDE_DROP_DOWN_BOX");
        intent.putExtra("state", "true");  
        mContext.sendBroadcast(intent);
    }
    
    private void showDropDown()
    {
        //允许下拉框
        Intent intent = new Intent();
        intent.setPackage("com.android.systemui");
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction("action.ACTION_API_HIDE_DROP_DOWN_BOX");
        intent.putExtra("state", "false");  
        mContext.sendBroadcast(intent);
    } 
}; 

SystemServer.java

注册上述服务

路径:framework/base/services/java/com/android/server/SystemServer.java

函数注册位置 private void startOtherServices(@NonNull TimingsTraceAndSlog t)

t.traceBegin("Start WSettingsService");
try {
    ServiceManager.addService(Context.WSETTINGS_SERVICE, new WSettingsService(context));
} 
catch (Throwable e) 
{
    Slog.e(TAG, "Failure starting WSettingsService", e);
}
t.traceEnd();

启动服务生效

路径: core/java/android/app/SystemServiceRegistry.java
...
    // Not instantiable.
    private SystemServiceRegistry() { }
    static {
             registerService(Context.WSETTINGS_SERVICE, WSettingsManager.class,
                new CachedServiceFetcher<WSettingsManager>(){
              @Override
              public WSettingsManager createService(ContextImpl ctx)  throws ServiceNotFoundException {
                       IBinder b = ServiceManager.getService(Context.WSETTINGS_SERVICE);
                IWSettingsService service = IWSettingsService.Stub.asInterface(b);
                return new WSettingsManager(ctx, service);
            }});
		//end, add by xiaoxuan
                ...

WSettingsManager.java

具体实现服务中接口的方法

路径:framework/base/core/java/android/app/WSettingsManager.java
package android.app;
 
import android.annotation.SdkConstant;
import android.annotation.SystemApi;
import android.content.Context;
import android.os.RemoteException;
import android.util.Log;
import android.os.Build;
import android.os.IWSettingsService;
import android.annotation.NonNull;
import android.annotation.Nullable;
import java.lang.String;
 
public class WSettingsManager {
	
	private static String TAG = "WSettingsManager";
    IWSettingsService mService;    //AIDL
 
    /* 下边的hide是隐藏的意思,因为系统服务注册函数也是hide的,所以这里需要添加hide,不添加的话编译会报错 */
	/**
	* @hide
	*/
    public WSettingsManager(Context ctx, IWSettingsService service){
        mService=service;
    }
    public void setSystemBarShow(@NonNull String type,boolean visibility)
    {
        try{
            mService.setSystemBarShow(type,visibility);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

引用类

framework/base/core/java/android/provider/Settings.java

    // by xiaoxuan
    /**
         * add by xiaoxuan
         * Disable drop-down box
         * @hide
         */
    // 必须加上@hide注解否则编译报错
    public static final String SYSTEM_HIDE_DROP_DOWN_BOX = "hide_dro_down_box";

core/java/android/content/Context.java

    /** @hide */
    @StringDef(suffix = { "_SERVICE" }, value = {
    ...
    WSETTINGS_SERVICE,
    ...
        
    public static final String WSETTINGS_SERVICE = "wsettings";

埋点类

framework/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java

    import android.provider.Settings;
    // by xiaoxuan 
    private Context mContext; 
        public CommandQueue(Context context) {
        this(context, null);
        mContext = context;
    }
    public CommandQueue(Context context, ProtoTracer protoTracer) {
        mProtoTracer = protoTracer;
        context.getSystemService(DisplayManager.class).registerDisplayListener(this, mHandler);
        // We always have default display.
        setDisabled(DEFAULT_DISPLAY, DISABLE_NONE, DISABLE2_NONE);
        mContext = context;
    }
        // TODO(b/118592525): add multi-display support if needed.
    public boolean panelsEnabled() {
        final int disabled1 = getDisabled1(DEFAULT_DISPLAY);
        final int disabled2 = getDisabled2(DEFAULT_DISPLAY);
        //return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
        //       && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
        //        && !ONLY_CORE_APPS;
        //add by xiaoxuan
        boolean isHide = Settings.System.getInt(
        mContext.getContentResolver(), Settings.SYSTEM_HIDE_DROP_DOWN_BOX, 0) != 0;
        if(isHide)
        {
            return false;
        } 
        else 
        {
            return (disabled1 & StatusBarManager.DISABLE_EXPAND) == 0
                        && (disabled2 & StatusBarManager.DISABLE2_NOTIFICATION_SHADE) == 0
                        && !ONLY_CORE_APPS;
        }
        //end, add by xiaoxuan
       
    }

framework/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java

    public static final String ACTION_API_HIDE_NAVIGATION = "action.ACTION_API_HIDE_NAVIGATION"; //隐藏导航栏广播
    public static final String ACTION_API_SHOW_NAVIGATION = "action.ACTION_API_SHOW_NAVIGATION"; //显示导航栏广播
    public static final String ACTION_API_HIDE_STATUS_BAR = "action.ACTION_API_HIDE_STATUS_BAR"; //隐藏狀態广播
	public static final String ACTION_API_SHOW_STATUS_BAR = "action.ACTION_API_SHOW_STATUS_BAR"; //顯示狀態蘭广播
	public static final String ACTION_API_HIDE_DROP_DOWN_BOX = "action.ACTION_API_HIDE_DROP_DOWN_BOX"; //下拉框廣播
	 private boolean mHideNavStatus = true;
    protected void registerBroadcastReceiver() {
        IntentFilter filter = new IntentFilter();
        //add by xiaoxuan 添加到广播队列里
		filter.addAction(ACTION_API_HIDE_NAVIGATION); 
		filter.addAction(ACTION_API_SHOW_NAVIGATION); 
		filter.addAction(ACTION_API_HIDE_STATUS_BAR); 
		filter.addAction(ACTION_API_SHOW_STATUS_BAR); 
		filter.addAction(ACTION_API_HIDE_DROP_DOWN_BOX);
		//------------------------------
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        filter.addAction(DevicePolicyManager.ACTION_SHOW_DEVICE_MONITORING_DIALOG);
        mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter, null, UserHandle.ALL);
    }
    
     private void hideNavigation() {
        if (mHideNavStatus){
            //Log.d(TAG,"====== hide Navigation ======");
            NavigationBarView mNavigationBarView = mNavigationBarController.getDefaultNavigationBarView();
 
            if (mNavigationBarView != null)
                mNavigationBarController.hideNavigationBar();
 
            mHideNavStatus = false;
        }
    }
       private void showNavigation() {
        if (!mHideNavStatus){
            //Log.d(TAG,"====== api show Navigation ======");
            NavigationBarView mNavigationBarView = mNavigationBarController.getDefaultNavigationBarView();
            if (mNavigationBarView == null)
                mNavigationBarController.createNavigationBars(true,null);
                       
            mHideNavStatus = true;
        }
    }
    
    private void showStatusBar() {
        if (mStatusBarView!=null){
            //Log.d(TAG,"====== show StatusBar ======");
            mStatusBarView.setVisibility(View.VISIBLE);
        }
    }
    private void hideStatusBar() {
        if (mStatusBarView != null){
           //Log.d(TAG,"====== hide StatusBar ======");
           mStatusBarView.setVisibility(View.GONE);
        }
    }
    
        private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (DEBUG) Log.v(TAG, "onReceive: " + intent);
            String action = intent.getAction();
            if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)) {
                KeyboardShortcuts.dismiss();
                if (mRemoteInputManager.getController() != null) {
                    mRemoteInputManager.getController().closeRemoteInputs();
                }
                if (mBubbleController.isStackExpanded()) {
                    mBubbleController.collapseStack();
                }
                if (mLockscreenUserManager.isCurrentProfile(getSendingUserId())) {
                    int flags = CommandQueue.FLAG_EXCLUDE_NONE;
                    String reason = intent.getStringExtra("reason");
                    if (reason != null && reason.equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
                        flags |= CommandQueue.FLAG_EXCLUDE_RECENTS_PANEL;
                    }
                    mShadeController.animateCollapsePanels(flags);
                }
            }
            // by xiaoxuan 
            else if(ACTION_API_HIDE_NAVIGATION.equals(action)) { 
				hideNavigation(); //隐藏导航栏
			}
            else if(ACTION_API_SHOW_NAVIGATION.equals(action)) { 
                showNavigation(); //显示导航栏
            }
            else if(ACTION_API_HIDE_STATUS_BAR.equals(action)) { 
                hideStatusBar();
            }
            else if(ACTION_API_SHOW_STATUS_BAR.equals(action)) { 
                showStatusBar();
            }
            else if(ACTION_API_HIDE_DROP_DOWN_BOX.equals(action)) {
                String state= intent.getStringExtra("state"); //解析出应用发送过来的参数值
                if (state != null && "true".equals(state)) {
                    Settings.System.putInt(context.getContentResolver(), Settings.SYSTEM_HIDE_DROP_DOWN_BOX, 1); //禁止下拉框
                } else {
                    Settings.System.putInt(context.getContentResolver(), Settings.SYSTEM_HIDE_DROP_DOWN_BOX, 0); //允许下拉框
                }
            }
            //--------------------------------------------------
            else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
                if (mNotificationShadeWindowController != null) {
                    mNotificationShadeWindowController.setNotTouchable(false);
                }
                if (mBubbleController.isStackExpanded()) {
                    mBubbleController.collapseStack();
                }
                finishBarAnimations();
                resetUserExpandedStates();
            }

packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java

    /**
     * by xiaoxuan 
     * hide 导航栏
     * */
     public void hideNavigationBar() { 
        Display[] displays = mDisplayManager.getDisplays();
        for (Display display : displays) {
            removeNavigationBar(display.getDisplayId());
        }
    }

到此代码部分整理完毕,请先执行make update-api更新系统API