- 新增 frameworks/base/packages/SystemUI/res/layout/power.xml
XML
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.navigationbar.buttons.KeyButtonView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/power"
android:layout_width="@dimen/navigation_key_width"
android:layout_height="match_parent"
android:layout_weight="0"
android:contentDescription="@string/accessibility_power"
android:paddingStart="@dimen/navigation_key_padding"
android:paddingEnd="@dimen/navigation_key_padding"
android:scaleType="center"
systemui:keyCode="0" />
- frameworks/base/packages/SystemUI/res/values/config.xml
默认状态下不显示新增的"Power"选项,在对应的overlay目录下可以将config_power_menu_show_enable设置成true.
XML
<!-- Insert power menu in navigation bar default if value is false-->
<bool name="config_power_menu_show_enable">false</bool>
3.frameworks/base/packages/SystemUI/res/values/strings.xml
XML
<!-- Content description of the power button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_power">Power</string>
4.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBar.java
java
private void prepareNavigationBarView() {
mView.reorient();
ButtonDispatcher recentsButton = mView.getRecentsButton();
recentsButton.setOnClickListener(this::onRecentsClick);
recentsButton.setOnTouchListener(this::onRecentsTouch);
ButtonDispatcher homeButton = mView.getHomeButton();
homeButton.setOnTouchListener(this::onHomeTouch);
homeButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
ButtonDispatcher backButton = mView.getBackButton();
backButton.setNavBarButtonClickLogger(mNavBarButtonClickLogger);
reconfigureHomeLongClick();
ButtonDispatcher accessibilityButton = mView.getAccessibilityButton();
accessibilityButton.setOnClickListener(this::onAccessibilityClick);
accessibilityButton.setOnLongClickListener(this::onAccessibilityLongClick);
updateAccessibilityStateFlags();
ButtonDispatcher imeSwitcherButton = mView.getImeSwitchButton();
imeSwitcherButton.setOnClickListener(this::onImeSwitcherClick);
// Insert a Power menu to the navigation bar 20250411 add start
ButtonDispatcher powerButton = mView.getPowerButton();
powerButton.setOnClickListener(mPowerClickListener);
// Insert a Power menu to the navigation bar 20250411 add end
updateScreenPinningGestures();
}
// Insert a Power menu to the navigation bar 20250411 add start
private View.OnClickListener mPowerClickListener = new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent("android.intent.action.POWER_MENU");
mContext.sendBroadcast(intent);
}
};
//Insert a Power menu to the navigation bar 20250411 add end
5.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarInflaterView.java
java
// Insert a Power menu to the navigation bar 20250411 add
public static final String POWER = "power";
private Context mContext;
private boolean mPowerMenuShowEnable = false;
public static final int SOHO_NAVIGATION_BAR_SIZE = 4;
// Insert a Power menu to the navigation bar 20250411 end
public NavigationBarInflaterView(Context context, AttributeSet attrs) {
super(context, attrs);
// Insert a Power menu to the navigation bar 20250411 add
mContext = context;
if (mContext != null) {
mPowerMenuShowEnable = mContext.getResources().getBoolean(
R.bool.config_power_menu_show_enable);
}
// Insert a Power menu to the navigation bar 20250411 end
createInflaters();
mOverviewProxyService = Dependency.get(OverviewProxyService.class);
mListener = new Listener(this);
mNavBarMode = Dependency.get(NavigationModeController.class).addListener(mListener);
}
protected void inflateLayout(String newLayout) {
mCurrentLayout = newLayout;
if (newLayout == null) {
newLayout = getDefaultLayout();
}
// Insert a Power menu to the navigation bar 20250411 modify start
if (mPowerMenuShowEnable) {
String[] sets = newLayout.split(GRAVITY_SEPARATOR, SOHO_NAVIGATION_BAR_SIZE);
if (sets.length != SOHO_NAVIGATION_BAR_SIZE) {
Log.d(TAG, "Invalid layout.");
newLayout = getDefaultLayout();
sets = newLayout.split(GRAVITY_SEPARATOR, SOHO_NAVIGATION_BAR_SIZE);
}
String[] start = sets[0].split(BUTTON_SEPARATOR);
String[] center = sets[1].split(BUTTON_SEPARATOR);
String[] end = sets[2].split(BUTTON_SEPARATOR);
String[] add = sets[3].split(BUTTON_SEPARATOR);
inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, true /* start */);
inflateButtons(start, mVertical.findViewById(R.id.ends_group),
true /* landscape */, true /* start */);
inflateButtons(center, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, false /* start */);
inflateButtons(center, mVertical.findViewById(R.id.ends_group),
true /* landscape */, false /* start */);
inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, false /* start */);
inflateButtons(end, mVertical.findViewById(R.id.ends_group),
true /* landscape */, false /* start */);
inflateButtons(add, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, false /* start */);
inflateButtons(add, mVertical.findViewById(R.id.ends_group),
true /* landscape */, false /* start */);
} else {
String[] sets = newLayout.split(GRAVITY_SEPARATOR, 3);
if (sets.length != 3) {
Log.d(TAG, "Invalid layout.");
newLayout = getDefaultLayout();
sets = newLayout.split(GRAVITY_SEPARATOR, 3);
}
String[] start = sets[0].split(BUTTON_SEPARATOR);
String[] center = sets[1].split(BUTTON_SEPARATOR);
String[] end = sets[2].split(BUTTON_SEPARATOR);
// Inflate these in start to end order or accessibility traversal will be messed up.
inflateButtons(start, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, true /* start */);
inflateButtons(start, mVertical.findViewById(R.id.ends_group),
true /* landscape */, true /* start */);
inflateButtons(center, mHorizontal.findViewById(R.id.center_group),
false /* landscape */, false /* start */);
inflateButtons(center, mVertical.findViewById(R.id.center_group),
true /* landscape */, false /* start */);
addGravitySpacer(mHorizontal.findViewById(R.id.ends_group));
addGravitySpacer(mVertical.findViewById(R.id.ends_group));
inflateButtons(end, mHorizontal.findViewById(R.id.ends_group),
false /* landscape */, false /* start */);
inflateButtons(end, mVertical.findViewById(R.id.ends_group),
true /* landscape */, false /* start */);
}
// Insert a Power menu to the navigation bar 20250411 modify end
updateButtonDispatchersCurrentView();
}
View createView(String buttonSpec, ViewGroup parent, LayoutInflater inflater) {
View v = null;
String button = extractButton(buttonSpec);
if (LEFT.equals(button)) {
button = extractButton(NAVSPACE);
} else if (RIGHT.equals(button)) {
button = extractButton(MENU_IME_ROTATE);
}
if (HOME.equals(button)) {
v = inflater.inflate(R.layout.home, parent, false);
} else if (BACK.equals(button)) {
v = inflater.inflate(R.layout.back, parent, false);
} else if (RECENT.equals(button)) {
v = inflater.inflate(R.layout.recent_apps, parent, false);
} else if (MENU_IME_ROTATE.equals(button)) {
v = inflater.inflate(R.layout.menu_ime, parent, false);
} else if (NAVSPACE.equals(button)) {
v = inflater.inflate(R.layout.nav_key_space, parent, false);
} else if (CLIPBOARD.equals(button)) {
v = inflater.inflate(R.layout.clipboard, parent, false);
} else if (CONTEXTUAL.equals(button)) {
v = inflater.inflate(R.layout.contextual, parent, false);
} else if (HOME_HANDLE.equals(button)) {
v = inflater.inflate(R.layout.home_handle, parent, false);
} else if (IME_SWITCHER.equals(button)) {
v = inflater.inflate(R.layout.ime_switcher, parent, false);
// Insert a Power menu to the navigation bar 20250411 add start
} else if (POWER.equals(button)) {
v = inflater.inflate(R.layout.power, parent, false);
// Insert a Power menu to the navigation bar 20250411 add end
} else if (button.startsWith(KEY)) {
String uri = extractImage(button);
int code = extractKeycode(button);
v = inflater.inflate(R.layout.custom_key, parent, false);
((KeyButtonView) v).setCode(code);
if (uri != null) {
if (uri.contains(":")) {
((KeyButtonView) v).loadAsync(Icon.createWithContentUri(uri));
} else if (uri.contains("/")) {
int index = uri.indexOf('/');
String pkg = uri.substring(0, index);
int id = Integer.parseInt(uri.substring(index + 1));
((KeyButtonView) v).loadAsync(Icon.createWithResource(pkg, id));
}
}
}
return v;
}
6.frameworks/base/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarView.java
java
// Insert a Power menu to the navigation bar 20250411 add
private KeyButtonDrawable mPowerIcon;
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
// Insert a Power menu to the navigation bar 20250411 add
mButtonDispatchers.put(R.id.power, new ButtonDispatcher(R.id.power));
}
// Insert a Power menu to the navigation bar 20250411 add start
public ButtonDispatcher getPowerButton() {
return mButtonDispatchers.get(R.id.power);
}
// Insert a Power menu to the navigation bar 20250411 add end
private void updateIcons(Configuration oldConfig) {
final boolean orientationChange = oldConfig.orientation != mConfiguration.orientation;
final boolean densityChange = oldConfig.densityDpi != mConfiguration.densityDpi;
final boolean dirChange = oldConfig.getLayoutDirection() != mConfiguration.getLayoutDirection();
if (orientationChange || densityChange) {
mDockedIcon = getDrawable(R.drawable.ic_sysbar_docked);
mHomeDefaultIcon = getHomeDrawable();
}
if (densityChange || dirChange) {
mRecentIcon = getDrawable(R.drawable.ic_sysbar_recent);
mContextualButtonGroup.updateIcons(mLightIconColor, mDarkIconColor);
}
if (orientationChange || densityChange || dirChange) {
mBackIcon = getBackDrawable();
}
// Insert a Power menu to the navigation bar 20250411 add
mPowerIcon = getDrawable(R.drawable.ic_settings_power);
}
public void updateNavButtonIcons() {
...
//Insert a Power menu to the navigation bar 20250411 add
getPowerButton().setImageDrawable(mPowerIcon);
}
7.frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
java
void init(Injector injector) {
mContext = injector.getContext();
...
//Insert a Power menu to the navigation bar 20250411 add start
IntentFilter mPower = new IntentFilter("android.intent.action.POWER_MENU");
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//show global actions dialog
showGlobalActionsInternal();
}
}, mPower);
//Insert a Power menu to the navigation bar 20250411 add end
// register for multiuser-relevant broadcasts
filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
mContext.registerReceiver(mMultiuserReceiver, filter);
...
}