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

Commit d09be7ed authored by Jason Monk's avatar Jason Monk Committed by Android (Google) Code Review
Browse files

Merge "New dialog for ignore battery optimizations" into mnc-dev

parents f8d131e1 3a90d7cc
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -944,6 +944,11 @@
        <activity android:name="Settings$HighPowerApplicationsActivity"
                android:label="@string/high_power_apps"
                android:taskAffinity="">
            <intent-filter android:priority="1">
                <action android:name="android.settings.IGNORE_BATTERY_OPTIMIZATION_SETTINGS" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="package" />
            </intent-filter>
            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
                android:value="com.android.settings.applications.ManageApplications" />
            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+47 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright (C) 2015 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.
-->

<com.android.settings.CheckableLinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:minHeight="?android:attr/listPreferredItemHeightSmall">

    <CheckedTextView
        android:id="@android:id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="?android:attr/textColorAlertDialogListItem"
        android:gravity="center_vertical"
        android:paddingStart="20dp"
        android:paddingEnd="?android:attr/dialogPreferredPadding"
        android:drawableStart="?android:attr/listChoiceIndicatorSingle"
        android:ellipsize="marquee" />


    <TextView android:id="@+android:id/summary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="4dp"
        android:paddingStart="52dp"
        android:textAppearance="?android:attr/textAppearanceListItemSecondary"
        android:textColor="?android:attr/textColorSecondary"
        android:maxLines="10" />

</com.android.settings.CheckableLinearLayout>
+72 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 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.settings;

import android.content.Context;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.widget.Checkable;
import android.widget.LinearLayout;

public class CheckableLinearLayout extends LinearLayout implements Checkable {

    private boolean mChecked;
    private float mDisabledAlpha;

    public CheckableLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedValue alpha = new TypedValue();
        context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, alpha, true);
        mDisabledAlpha = alpha.getFloat();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
        final int N = getChildCount();
        for (int i = 0; i < N; i++) {
            getChildAt(i).setAlpha(enabled ? 1 : mDisabledAlpha);
        }
    }

    @Override
    public void setChecked(boolean checked) {
        mChecked = checked;
        updateChecked();
    }

    @Override
    public boolean isChecked() {
        return mChecked;
    }

    @Override
    public void toggle() {
        setChecked(!mChecked);
    }

    private void updateChecked() {
        final int N = getChildCount();
        for (int i = 0; i < N; i++) {
            View child = getChildAt(i);
            if (child instanceof Checkable) {
                ((Checkable) child).setChecked(mChecked);
            }
        }
    }

}
+11 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManager;
import android.preference.PreferenceFrameLayout;
import android.provider.Settings;
import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
@@ -239,6 +240,15 @@ public class ManageApplications extends InstrumentedFragment
            mListType = LIST_TYPE_HIGH_POWER;
            // Default to showing system.
            mShowSystem = true;
            if (intent != null && Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS
                    .equals(intent.getAction())) {
                mCurrentPkgName = intent.getData().getSchemeSpecificPart();
                if (mCurrentPkgName != null) {
                    mCurrentUid = mApplicationsState.getEntry(mCurrentPkgName,
                            UserHandle.myUserId()).info.uid;
                    startApplicationDetailsActivity();
                }
            }
        } else {
            mListType = LIST_TYPE_MAIN;
        }
@@ -440,7 +450,7 @@ public class ManageApplications extends InstrumentedFragment
                startAppInfoFragment(AppStorageSettings.class, R.string.storage_settings);
                break;
            case LIST_TYPE_HIGH_POWER:
                startAppInfoFragment(HighPowerDetail.class, R.string.high_power_apps);
                HighPowerDetail.show(getActivity(), mCurrentPkgName);
                break;
            // TODO: Figure out if there is a way where we can spin up the profile's settings
            // process ahead of time, to avoid a long load of data when user clicks on a managed app.
+88 −31
Original line number Diff line number Diff line
@@ -16,60 +16,85 @@

package com.android.settings.fuelgauge;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.SwitchPreference;
import android.util.Pair;
import android.util.SparseBooleanArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import com.android.internal.logging.MetricsLogger;
import com.android.settings.R;
import com.android.settings.applications.AppInfoWithHeader;
import com.android.settings.applications.AppInfoBase;
import com.android.settingslib.applications.ApplicationsState.AppEntry;

public class HighPowerDetail extends AppInfoWithHeader implements OnPreferenceChangeListener {

    private static final String KEY_HIGH_POWER_SWITCH = "high_power_switch";
public class HighPowerDetail extends DialogFragment implements OnClickListener {

    private final PowerWhitelistBackend mBackend = PowerWhitelistBackend.getInstance();

    private SwitchPreference mUsageSwitch;
    private String mPackageName;
    private CharSequence mLabel;
    private Adapter mAdapter;
    private int mSelectedIndex;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        addPreferencesFromResource(R.xml.high_power_details);
        mUsageSwitch = (SwitchPreference) findPreference(KEY_HIGH_POWER_SWITCH);
        mUsageSwitch.setOnPreferenceChangeListener(this);
        mPackageName = getArguments().getString(AppInfoBase.ARG_PACKAGE_NAME);
        PackageManager pm = getContext().getPackageManager();
        try {
            mLabel = pm.getApplicationInfo(mPackageName, 0).loadLabel(pm);
        } catch (NameNotFoundException e) {
            mLabel = mPackageName;
        }
        mAdapter = new Adapter(getContext(), R.layout.radio_with_summary);
        mAdapter.add(new Pair<String, String>(getString(R.string.ignore_optimizations_on),
                getString(R.string.ignore_optimizations_on_desc)));
        mAdapter.add(new Pair<String, String>(getString(R.string.ignore_optimizations_off),
                getString(R.string.ignore_optimizations_off_desc)));
        mSelectedIndex = mBackend.isWhitelisted(mPackageName) ? 0 : 1;
        if (mBackend.isSysWhitelisted(mPackageName)) {
            mAdapter.setEnabled(1, false);
        }
    }

    @Override
    protected boolean refreshUi() {
        mUsageSwitch.setEnabled(!mBackend.isSysWhitelisted(mPackageName));
        mUsageSwitch.setChecked(mBackend.isWhitelisted(mPackageName));
        return true;
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        AlertDialog.Builder b = new AlertDialog.Builder(getContext())
                .setTitle(getString(R.string.ignore_optimizations_title, mLabel))
                .setNegativeButton(R.string.cancel, null)
                .setSingleChoiceItems(mAdapter, mSelectedIndex, this);
        if (!mBackend.isSysWhitelisted(mPackageName)) {
            b.setPositiveButton(R.string.done, this);
        }
        return b.create();
    }

    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
        if (newValue == Boolean.TRUE) {
    public void onClick(DialogInterface dialog, int which) {
        if (which == DialogInterface.BUTTON_POSITIVE) {
            boolean newValue = mSelectedIndex == 0;
            boolean oldValue = mBackend.isWhitelisted(mPackageName);
            if (newValue != oldValue) {
                if (newValue) {
                    mBackend.addApp(mPackageName);
                } else {
                    mBackend.removeApp(mPackageName);
                }
        return true;
            }

    @Override
    protected AlertDialog createDialog(int id, int errorCode) {
        return null;
        } else {
            mSelectedIndex = which;
        }

    @Override
    protected int getMetricsCategory() {
        return MetricsLogger.FUELGAUGE_HIGH_POWER_DETAILS;
    }

    public static CharSequence getSummary(Context context, AppEntry entry) {
@@ -81,4 +106,36 @@ public class HighPowerDetail extends AppInfoWithHeader implements OnPreferenceCh
                ? R.string.high_power_on : R.string.high_power_off);
    }

    public static void show(Activity activity, String packageName) {
        HighPowerDetail fragment = new HighPowerDetail();
        Bundle args = new Bundle();
        args.putString(AppInfoBase.ARG_PACKAGE_NAME, packageName);
        fragment.setArguments(args);
        fragment.show(activity.getFragmentManager(), HighPowerDetail.class.getSimpleName());
    }

    private class Adapter extends ArrayAdapter<Pair<String, String>> {
        private final SparseBooleanArray mEnabled = new SparseBooleanArray();

        public Adapter(Context context, int resource) {
            super(context, resource, android.R.id.title);
        }

        public void setEnabled(int index, boolean enabled) {
            mEnabled.put(index, enabled);
        }

        public boolean isEnabled(int position) {
            return mEnabled.get(position, true);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = super.getView(position, convertView, parent);
            ((TextView) view.findViewById(android.R.id.title)).setText(getItem(position).first);
            ((TextView) view.findViewById(android.R.id.summary)).setText(getItem(position).second);
            view.setEnabled(isEnabled(position));
            return view;
        }
    }
}