UsageAccessDetails.java revision 6ecca51254a6f2ac3b82149563cd02e48c579af6
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.settings.applications;
17
18import android.app.AlertDialog;
19import android.app.AppOpsManager;
20import android.content.ActivityNotFoundException;
21import android.content.ComponentName;
22import android.content.Context;
23import android.content.Intent;
24import android.content.pm.PackageManager;
25import android.content.pm.ResolveInfo;
26import android.os.Bundle;
27import android.os.UserHandle;
28import android.preference.Preference;
29import android.preference.Preference.OnPreferenceChangeListener;
30import android.preference.Preference.OnPreferenceClickListener;
31import android.preference.SwitchPreference;
32import android.provider.Settings;
33import android.util.Log;
34
35import com.android.internal.logging.MetricsLogger;
36import com.android.settings.R;
37import com.android.settings.applications.AppStateUsageBridge.UsageState;
38
39public class UsageAccessDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
40        OnPreferenceClickListener {
41
42    private static final String KEY_USAGE_SWITCH = "usage_switch";
43    private static final String KEY_USAGE_PREFS = "app_usage_preference";
44
45    // Use a bridge to get the usage stats but don't initialize it to connect with all state.
46    // TODO: Break out this functionality into its own class.
47    private AppStateUsageBridge mUsageBridge;
48    private AppOpsManager mAppOpsManager;
49    private SwitchPreference mSwitchPref;
50    private Preference mUsagePrefs;
51    private Intent mSettingsIntent;
52    private UsageState mUsageState;
53
54    @Override
55    public void onCreate(Bundle savedInstanceState) {
56        super.onCreate(savedInstanceState);
57
58        Context context = getActivity();
59        mUsageBridge = new AppStateUsageBridge(context, mState, null);
60        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
61
62        addPreferencesFromResource(R.xml.usage_access_details);
63        mSwitchPref = (SwitchPreference) findPreference(KEY_USAGE_SWITCH);
64        mUsagePrefs = findPreference(KEY_USAGE_PREFS);
65
66        mSwitchPref.setOnPreferenceChangeListener(this);
67        mUsagePrefs.setOnPreferenceClickListener(this);
68
69        mSettingsIntent = new Intent(Intent.ACTION_MAIN)
70                .addCategory(Settings.INTENT_CATEGORY_USAGE_ACCESS_CONFIG)
71                .setPackage(mPackageName);
72    }
73
74    @Override
75    public boolean onPreferenceClick(Preference preference) {
76        if (preference == mUsagePrefs) {
77            if (mSettingsIntent != null) {
78                try {
79                    getActivity().startActivityAsUser(mSettingsIntent, new UserHandle(mUserId));
80                } catch (ActivityNotFoundException e) {
81                    Log.w(TAG, "Unable to launch app usage access settings " + mSettingsIntent, e);
82                }
83            }
84            return true;
85        }
86        return false;
87    }
88
89    @Override
90    public boolean onPreferenceChange(Preference preference, Object newValue) {
91        if (preference == mSwitchPref) {
92            if (mUsageState != null && (Boolean) newValue != mUsageState.hasAccess()) {
93                setHasAccess(!mUsageState.hasAccess());
94                refreshUi();
95            }
96            return true;
97        }
98        return false;
99    }
100
101    private void setHasAccess(boolean newState) {
102        mAppOpsManager.setMode(AppOpsManager.OP_GET_USAGE_STATS, mPackageInfo.applicationInfo.uid,
103                mPackageName, newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_IGNORED);
104    }
105
106    @Override
107    protected boolean refreshUi() {
108        mUsageState = mUsageBridge.getUsageInfo(mPackageName,
109                mPackageInfo.applicationInfo.uid);
110
111        boolean hasAccess = mUsageState.hasAccess();
112        mSwitchPref.setChecked(hasAccess);
113        mUsagePrefs.setEnabled(hasAccess);
114
115        ResolveInfo resolveInfo = mPm.resolveActivityAsUser(mSettingsIntent,
116                PackageManager.GET_META_DATA, mUserId);
117        if (resolveInfo != null) {
118            if (findPreference(KEY_USAGE_PREFS) == null) {
119                getPreferenceScreen().addPreference(mUsagePrefs);
120            }
121            Bundle metaData = resolveInfo.activityInfo.metaData;
122            mSettingsIntent.setComponent(new ComponentName(resolveInfo.activityInfo.packageName,
123                    resolveInfo.activityInfo.name));
124            if (metaData != null
125                    && metaData.containsKey(Settings.METADATA_USAGE_ACCESS_REASON)) {
126                mSwitchPref.setSummary(
127                        metaData.getString(Settings.METADATA_USAGE_ACCESS_REASON));
128            }
129        } else {
130            if (findPreference(KEY_USAGE_PREFS) != null) {
131                getPreferenceScreen().removePreference(mUsagePrefs);
132            }
133        }
134
135        return true;
136    }
137
138    @Override
139    protected AlertDialog createDialog(int id, int errorCode) {
140        return null;
141    }
142
143    @Override
144    protected int getMetricsCategory() {
145        return MetricsLogger.APPLICATIONS_USAGE_ACCESS_DETAIL;
146    }
147
148}
149