1/*
2 * Copyright (C) 2014 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 */
16
17package com.android.tv.settings.about;
18
19import com.android.tv.settings.R;
20
21import com.android.tv.settings.PreferenceUtils;
22
23import com.android.tv.settings.dialog.old.Action;
24import com.android.tv.settings.dialog.old.ActionAdapter;
25import com.android.tv.settings.dialog.old.ActionFragment;
26import com.android.tv.settings.dialog.old.ContentFragment;
27import com.android.tv.settings.dialog.old.DialogActivity;
28import com.android.tv.settings.dialog.old.TosWebViewFragment;
29
30import com.android.tv.settings.name.DeviceManager;
31
32import android.app.Fragment;
33import android.app.FragmentTransaction;
34import android.content.ComponentName;
35import android.content.Intent;
36import android.content.pm.PackageManager;
37import android.content.pm.ResolveInfo;
38import android.os.Build;
39import android.os.Bundle;
40import android.os.SystemClock;
41import android.text.TextUtils;
42import android.widget.Toast;
43
44import java.util.ArrayList;
45import java.util.List;
46
47/**
48 * Activity which shows the build / model / legal info / etc.
49 */
50public class AboutActivity extends DialogActivity implements ActionAdapter.Listener,
51        ActionAdapter.OnFocusListener {
52
53    /**
54     * Action key for legal actions container.
55     */
56    private static final String KEY_LEGAL_INFO = "about_legal_info";
57
58    /**
59     * Action key for legal open source license action.
60     */
61    private static final String KEY_LEGAL_INFO_OPEN_SOURCE_LICENSES =
62            "about_legal_info_open_source_licenses";
63
64    /**
65     * Action keys for legal terms.
66     */
67    private static final String TERMS_OF_SERVICE = "terms_of_service";
68    private static final String PRIVACY_POLICY = "privacy_policy";
69    private static final String ADDITIONAL_TERMS = "additional_terms";
70
71    private static final String KEY_BUILD = "build";
72    private static final String KEY_VERSION = "version";
73
74    /**
75     * Intent action of SettingsLicenseActivity.
76     */
77    private static final String SETTINGS_LEGAL_LICENSE_INTENT_ACTION = "android.settings.LICENSE";
78
79    /**
80     * Intent action of device name activity.
81     */
82    private static final String SETTINGS_DEVICE_NAME_INTENT_ACTION =
83        "android.settings.DEVICE_NAME";
84
85    /**
86     * Intent to launch ads activity.
87     */
88    private static final String SETTINGS_ADS_ACTIVITY_PACKAGE = "com.google.android.gms";
89    private static final String SETTINGS_ADS_ACTIVITY_ACTION =
90            "com.google.android.gms.settings.ADS_PRIVACY";
91
92    /**
93     * Intent component to launch PlatLogo Easter egg.
94     */
95    private static final ComponentName mPlatLogoActivity = new ComponentName("android",
96            "com.android.internal.app.PlatLogoActivity");
97
98    /**
99     * Number of clicks it takes to be a developer.
100     */
101    private static final int NUM_DEVELOPER_CLICKS = 7;
102
103    private int mDeveloperClickCount;
104    private PreferenceUtils mPreferenceUtils;
105    private Toast mToast;
106    private int mSelectedIndex;
107    private long[] mHits = new long[3];
108    private int mHitsIndex;
109
110    @Override
111    protected void onCreate(Bundle savedInstanceState) {
112        super.onCreate(savedInstanceState);
113        mPreferenceUtils = new PreferenceUtils(this);
114        setContentAndActionFragments(ContentFragment.newInstance(
115                        getString(R.string.about_preference), null, null, R.drawable.ic_settings_about,
116                        getResources().getColor(R.color.icon_background)),
117                ActionFragment.newInstance(getActions()));
118        mSelectedIndex = 0;
119    }
120
121    @Override
122    public void onResume() {
123        super.onResume();
124        mDeveloperClickCount = 0;
125        setActionFragment(ActionFragment.newInstance(getActions(), mSelectedIndex), false);
126    }
127
128    @Override
129    public void onActionFocused(Action action) {
130        mSelectedIndex = getActions().indexOf(action);
131    }
132
133    @Override
134    public void onActionClicked(Action action) {
135        final String key = action.getKey();
136        if (TextUtils.equals(key, KEY_BUILD)) {
137            mDeveloperClickCount++;
138            if (!mPreferenceUtils.isDeveloperEnabled()) {
139                int numLeft = NUM_DEVELOPER_CLICKS - mDeveloperClickCount;
140                if (numLeft < 3 && numLeft > 0) {
141                    showToast(getResources().getQuantityString(
142                            R.plurals.show_dev_countdown, numLeft, numLeft));
143                }
144                if (numLeft == 0) {
145                    mPreferenceUtils.setDeveloperEnabled(true);
146                    showToast(getString(R.string.show_dev_on));
147                    mDeveloperClickCount = 0;
148                }
149            } else {
150                if (mDeveloperClickCount > 3) {
151                    showToast(getString(R.string.show_dev_already));
152                }
153            }
154        } else if (TextUtils.equals(key, KEY_VERSION)) {
155            mHits[mHitsIndex] = SystemClock.uptimeMillis();
156            mHitsIndex = (mHitsIndex + 1) % mHits.length;
157            if (mHits[mHitsIndex] >= SystemClock.uptimeMillis() - 500) {
158                Intent intent = new Intent();
159                intent.setComponent(mPlatLogoActivity);
160                startActivity(intent);
161            }
162        } else if (TextUtils.equals(key, TERMS_OF_SERVICE)) {
163            displayFragment(TosWebViewFragment.
164                newInstance(TosWebViewFragment.SHOW_TERMS_OF_SERVICE));
165        } else if (TextUtils.equals(key, PRIVACY_POLICY)) {
166            displayFragment(TosWebViewFragment.newInstance(TosWebViewFragment.SHOW_PRIVACY_POLICY));
167        } else if (TextUtils.equals(key, ADDITIONAL_TERMS)) {
168            displayFragment(
169                TosWebViewFragment.newInstance (TosWebViewFragment.SHOW_ADDITIONAL_TERMS));
170        } else if (TextUtils.equals(key, KEY_LEGAL_INFO)) {
171            ArrayList<Action> actions = getLegalActions();
172            setContentAndActionFragments(ContentFragment.newInstance(
173                    getString(R.string.about_legal_info), null, null),
174                    ActionFragment.newInstance(actions));
175        } else {
176            Intent intent = action.getIntent();
177            if (intent != null) {
178                startActivity(intent);
179            }
180        }
181    }
182
183    private ArrayList<Action> getLegalActions() {
184        ArrayList<Action> actions = new ArrayList<Action>();
185        Intent licensesIntent = new Intent(SETTINGS_LEGAL_LICENSE_INTENT_ACTION);
186        actions.add(new Action.Builder()
187                .key(KEY_LEGAL_INFO_OPEN_SOURCE_LICENSES)
188                .intent(licensesIntent)
189                .title(getString(R.string.about_legal_license))
190                .build());
191
192        actions.add(new Action.Builder()
193                .key(TERMS_OF_SERVICE)
194                .title(getString(R.string.about_terms_of_service))
195                .build());
196
197        actions.add(new Action.Builder()
198                .key(PRIVACY_POLICY)
199                .title(getString(R.string.about_privacy_policy))
200                .build());
201
202        actions.add(new Action.Builder()
203                .key(ADDITIONAL_TERMS)
204                .title(getString(R.string.about_additional_terms))
205                .build());
206
207        return actions;
208    }
209
210    private ArrayList<Action> getActions() {
211        ArrayList<Action> actions = new ArrayList<Action>();
212        actions.add(new Action.Builder()
213                .key("update")
214                .title(getString(R.string.about_system_update))
215                .intent(new Intent("android.settings.SYSTEM_UPDATE_SETTINGS"))
216                .build());
217        actions.add(new Action.Builder()
218                .key("name")
219                .title(getString(R.string.device_name))
220                .description(DeviceManager.getDeviceName(this))
221                .intent(new Intent(SETTINGS_DEVICE_NAME_INTENT_ACTION))
222                .build());
223        actions.add(new Action.Builder()
224                .key(KEY_LEGAL_INFO)
225                .title(getString(R.string.about_legal_info))
226                .build());
227        Intent adsIntent = new Intent();
228        adsIntent.setPackage(SETTINGS_ADS_ACTIVITY_PACKAGE);
229        adsIntent.setAction(SETTINGS_ADS_ACTIVITY_ACTION);
230        adsIntent.addCategory(Intent.CATEGORY_DEFAULT);
231        List<ResolveInfo> resolveInfos = getPackageManager().queryIntentActivities(adsIntent,
232                PackageManager.MATCH_DEFAULT_ONLY);
233        if (!resolveInfos.isEmpty()) {
234            // Launch the phone ads id activity.
235            actions.add(new Action.Builder()
236                    .key("ads")
237                    .title(getString(R.string.about_ads))
238                    .intent(adsIntent)
239                    .enabled(true)
240                    .build());
241        }
242        actions.add(new Action.Builder()
243                .key("model")
244                .title(getString(R.string.about_model))
245                .description(Build.MODEL)
246                .enabled(false)
247                .build());
248        actions.add(new Action.Builder()
249                .key(KEY_VERSION)
250                .title(getString(R.string.about_version))
251                .description(Build.VERSION.RELEASE)
252                .enabled(true)
253                .build());
254        actions.add(new Action.Builder()
255                .key("serial")
256                .title(getString(R.string.about_serial))
257                .description(Build.SERIAL)
258                .enabled(false)
259                .build());
260        actions.add(new Action.Builder()
261                .key(KEY_BUILD)
262                .title(getString(R.string.about_build))
263                .description(Build.DISPLAY)
264                .enabled(true)
265                .build());
266        return actions;
267    }
268
269    private void displayFragment(Fragment fragment) {
270        getFragmentManager()
271            .beginTransaction()
272            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
273            .replace(android.R.id.content, fragment)
274            .addToBackStack(null)
275            .commit();
276    }
277
278    private void showToast(String toastString) {
279        if (mToast != null) {
280            mToast.cancel();
281        }
282        mToast = Toast.makeText(this,  toastString, Toast.LENGTH_SHORT);
283        mToast.show();
284    }
285}
286