Skip to content

Commit 3b6643a

Browse files
kaluoshiateek-ujjawal
authored andcommitted
OnTheSpot: Forward implement infrastructure [1/2]
* An alert dialog in da face system to explain features and behaviours to users. * Implements Gif support: Now features can be explained in yummy animated goodness (cit. Aaron) GifView supports adding gifs programmatically or via xml using custom:gif="" Contributors: @D4rKn3sSyS @aaronpoweruser @Anu6is @bigbrother1984 Signed-off-by: @bigbrother1984 <[email protected]> Change-Id: I725a8164c13c5381ddbc15fde29902a258c1ecc4 Conflicts: core/res/res/values/bliss_symbols.xml Signed-off-by: W4TCH0UT <[email protected]> Conflicts: core/java/android/util/SettingConfirmationHelper.java core/res/res/layout/setting_confirmation_dialog.xml core/res/res/values/cmr_symbols.xml core/res/res/values/tr_styles.xml
1 parent 940e979 commit 3b6643a

File tree

10 files changed

+502
-4
lines changed

10 files changed

+502
-4
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (C) 2014, ParanoidAndroid Project
3+
* Copyrighy (c) 2015, METALLIUM OS Project
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package android.util;
19+
20+
import android.app.ActivityManager;
21+
import android.app.AlertDialog;
22+
import android.content.Context;
23+
import android.content.DialogInterface;
24+
import android.graphics.drawable.Drawable;
25+
import android.view.LayoutInflater;
26+
import android.view.View;
27+
import android.view.Window;
28+
import android.view.WindowManager;
29+
import android.widget.GifView;
30+
import android.widget.ImageView;
31+
import android.provider.Settings;
32+
33+
import java.io.InputStream;
34+
35+
import com.android.internal.R;
36+
37+
/**
38+
* Hide from public API
39+
* @hide
40+
*/
41+
public class SettingConfirmationHelper {
42+
43+
private static final int NOT_SET = 0;
44+
private static final int ENABLED = 1;
45+
private static final int DISABLED = 2;
46+
private static final int ASK_LATER = 3;
47+
48+
/**
49+
* @hide
50+
*/
51+
public static interface OnSelectListener {
52+
void onSelect(boolean enabled);
53+
}
54+
55+
/**
56+
* @hide
57+
*/
58+
public static void showConfirmationDialogForSetting(final Context context, String title, String msg, Drawable hint,
59+
final String setting, final OnSelectListener listener) {
60+
int mCurrentStatus = Settings.System.getInt(context.getContentResolver(), setting, NOT_SET);
61+
if (mCurrentStatus == ENABLED || mCurrentStatus == DISABLED) return;
62+
63+
LayoutInflater layoutInflater = LayoutInflater.from(context);
64+
View dialogLayout = layoutInflater.inflate(R.layout.setting_confirmation_dialog, null);
65+
final ImageView visualHint = (ImageView)
66+
dialogLayout.findViewById(R.id.setting_confirmation_dialog_visual_hint);
67+
visualHint.setImageDrawable(hint);
68+
visualHint.setVisibility(View.VISIBLE);
69+
70+
AlertDialog dialog = createDialog(context,title,msg,dialogLayout,setting,listener);
71+
initWindow(dialog).show();
72+
}
73+
74+
/**
75+
* @hide
76+
*/
77+
public static void showConfirmationDialogForSetting(final Context context, String title, String msg, InputStream gif,
78+
final String setting, final OnSelectListener listener) {
79+
int mCurrentStatus = Settings.System.getInt(
80+
context.getContentResolver(), setting, NOT_SET);
81+
if (mCurrentStatus == ENABLED || mCurrentStatus == DISABLED) return;
82+
83+
LayoutInflater layoutInflater = LayoutInflater.from(context);
84+
View dialogLayout = layoutInflater.inflate(R.layout.setting_confirmation_dialog, null);
85+
final GifView gifView = (GifView)
86+
dialogLayout.findViewById(R.id.setting_confirmation_dialog_visual_gif);
87+
gifView.setGifResource(gif);
88+
gifView.setVisibility(View.VISIBLE);
89+
90+
AlertDialog dialog = createDialog(context,title,msg,dialogLayout,setting,listener);
91+
initWindow(dialog).show();
92+
}
93+
94+
private static AlertDialog initWindow(AlertDialog dialog) {
95+
Window dialogWindow = dialog.getWindow();
96+
dialogWindow.setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL);
97+
return dialog;
98+
}
99+
100+
private static AlertDialog createDialog(final Context context, String title, String msg, View view,
101+
final String setting, final OnSelectListener listener) {
102+
final int currentUserId = ActivityManager.getCurrentUser();
103+
AlertDialog.Builder builder = new AlertDialog.Builder(context);
104+
105+
builder.setView(view, 10, 10, 10, 20);
106+
builder.setTitle(title);
107+
builder.setMessage(msg);
108+
builder.setPositiveButton(R.string.setting_confirmation_yes,
109+
new DialogInterface.OnClickListener() {
110+
public void onClick(DialogInterface dialog, int which) {
111+
Settings.System.putIntForUser(context.getContentResolver(), setting,
112+
ENABLED, currentUserId);
113+
if (listener == null) return;
114+
listener.onSelect(true);
115+
}
116+
}
117+
);
118+
builder.setNeutralButton(R.string.setting_confirmation_ask_me_later,
119+
new DialogInterface.OnClickListener() {
120+
public void onClick(DialogInterface dialog, int which) {
121+
Settings.System.putIntForUser(context.getContentResolver(), setting,
122+
ASK_LATER, currentUserId);
123+
if (listener == null) return;
124+
listener.onSelect(false);
125+
}
126+
}
127+
);
128+
builder.setNegativeButton(R.string.setting_confirmation_no,
129+
new DialogInterface.OnClickListener() {
130+
public void onClick(DialogInterface dialog, int which) {
131+
Settings.System.putIntForUser(context.getContentResolver(), setting,
132+
DISABLED, currentUserId);
133+
if (listener == null) return;
134+
listener.onSelect(false);
135+
}
136+
}
137+
);
138+
builder.setCancelable(false);
139+
140+
return builder.create();
141+
}
142+
143+
}
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* Copyright (C) 2014 ParanoidAndroid 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+
17+
package android.widget;
18+
19+
import android.content.Context;
20+
import android.content.res.TypedArray;
21+
import android.graphics.Canvas;
22+
import android.graphics.Movie;
23+
import android.graphics.Rect;
24+
import android.view.LayoutInflater;
25+
import android.view.View;
26+
import android.view.Window;
27+
import android.util.AttributeSet;
28+
29+
import java.io.InputStream;
30+
31+
import com.android.internal.R;
32+
33+
/**
34+
* Hide from public API
35+
* @hide
36+
*/
37+
public class GifView extends View {
38+
39+
private static final int DEFAULT_DURATION = 1000; // 1 second
40+
41+
private int mMovieResourceId = -1;
42+
private Movie mMovie;
43+
44+
private long mMovieStart;
45+
private int mCurrentAnimationTime;
46+
47+
private float mLeft;
48+
private float mTop;
49+
private float mScale;
50+
51+
private int mMeasuredMovieWidth;
52+
private int mMeasuredMovieHeight;
53+
54+
public GifView(Context context) {
55+
this(context, null);
56+
}
57+
58+
public GifView(Context context, AttributeSet attrs) {
59+
this(context, attrs, R.styleable.CustomTheme_gifViewStyle);
60+
}
61+
62+
public GifView(Context context, AttributeSet attrs, int defStyle) {
63+
super(context, attrs, defStyle);
64+
setViewAttributes(context, attrs, defStyle);
65+
}
66+
67+
public void setGifResource(InputStream gifStream) {
68+
mMovieResourceId = 0;
69+
mMovie = Movie.decodeStream(gifStream);
70+
requestLayout();
71+
}
72+
73+
private void setViewAttributes(Context context, AttributeSet attrs, int defStyle) {
74+
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
75+
76+
if (attrs != null) {
77+
final TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.GifView, defStyle,
78+
0); //TODO set a sane defualt
79+
80+
mMovieResourceId = array.getResourceId(R.styleable.GifView_gif, -1);
81+
array.recycle();
82+
}
83+
84+
if (mMovieResourceId != -1) {
85+
mMovie = Movie.decodeStream(getResources().openRawResource(mMovieResourceId));
86+
}
87+
}
88+
89+
@Override
90+
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
91+
92+
if (mMovie != null) {
93+
int movieWidth = mMovie.width();
94+
int movieHeight = mMovie.height();
95+
96+
float scaleH = 1f;
97+
int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);
98+
99+
if (measureModeWidth != MeasureSpec.UNSPECIFIED) {
100+
int maximumWidth = MeasureSpec.getSize(widthMeasureSpec);
101+
if (movieWidth > maximumWidth) {
102+
scaleH = (float) movieWidth / (float) maximumWidth;
103+
}
104+
}
105+
106+
float scaleW = 1f;
107+
int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);
108+
109+
if (measureModeHeight != MeasureSpec.UNSPECIFIED) {
110+
int maximumHeight = MeasureSpec.getSize(heightMeasureSpec);
111+
if (movieHeight > maximumHeight) {
112+
scaleW = (float) movieHeight / (float) maximumHeight;
113+
}
114+
}
115+
116+
mScale = 1f / Math.max(scaleH, scaleW);
117+
118+
mMeasuredMovieWidth = (int) (movieWidth * mScale);
119+
mMeasuredMovieHeight = (int) (movieHeight * mScale);
120+
121+
setMeasuredDimension(mMeasuredMovieWidth, mMeasuredMovieHeight);
122+
123+
} else {
124+
setMeasuredDimension(getSuggestedMinimumWidth(), getSuggestedMinimumHeight());
125+
}
126+
}
127+
128+
@Override
129+
protected void onLayout(boolean changed, int l, int t, int r, int b) {
130+
super.onLayout(changed, l, t, r, b);
131+
mLeft = (getWidth() - mMeasuredMovieWidth) / 2f;
132+
mTop = (getHeight() - mMeasuredMovieHeight) / 2f;
133+
}
134+
135+
@Override
136+
protected void onDraw(Canvas canvas) {
137+
if (mMovie != null) {
138+
updateAnimationTime();
139+
drawMovieFrame(canvas);
140+
postInvalidateOnAnimation();
141+
}
142+
}
143+
144+
private void updateAnimationTime() {
145+
long now = android.os.SystemClock.uptimeMillis();
146+
147+
if (mMovieStart == 0) {
148+
mMovieStart = now;
149+
}
150+
151+
int dur = mMovie.duration();
152+
153+
if (dur == 0) {
154+
dur = DEFAULT_DURATION;
155+
}
156+
157+
mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);
158+
}
159+
160+
private void drawMovieFrame(Canvas canvas) {
161+
mMovie.setTime(mCurrentAnimationTime);
162+
canvas.save(Canvas.MATRIX_SAVE_FLAG);
163+
canvas.scale(mScale, mScale);
164+
mMovie.draw(canvas, mLeft / mScale, mTop / mScale);
165+
canvas.restore();
166+
}
167+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!-- Copyright (C) 2014 ParanoidAndroid 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+
17+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
18+
android:layout_width="match_parent"
19+
android:layout_height="match_parent" >
20+
<ImageView
21+
android:id="@+id/setting_confirmation_dialog_visual_hint"
22+
android:layout_width="wrap_content"
23+
android:layout_height="wrap_content"
24+
android:layout_centerInParent="true"
25+
android:visibility="gone" />
26+
27+
<android.widget.GifView
28+
android:id="@+id/setting_confirmation_dialog_visual_gif"
29+
android:layout_width="wrap_content"
30+
android:layout_height="wrap_content"
31+
android:layout_centerInParent="true"
32+
android:visibility="gone" />
33+
34+
</RelativeLayout>

core/res/res/values/tr_attrs.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,11 @@
2020
<!-- No added attributes at this time -->
2121
</declare-styleable>
2222

23+
<declare-styleable name="GifView">
24+
<attr name="gif" format="reference" />
25+
</declare-styleable>
26+
<declare-styleable name="CustomTheme">
27+
<attr name="gifViewStyle" format="reference" />
28+
</declare-styleable>
29+
2330
</resources>

core/res/res/values/tr_strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,9 @@
4343
<!-- Error description on theme switch with ligtsensor mode enabled -->
4444
<string name="theme_auto_switch_mode_error">Automatic light condition change mode is enabled. Manual switching is not possible.</string>
4545

46+
<!-- Setting confirmation dialog strings. Shown when any UI interaction can be modified by user input -->
47+
<string name="setting_confirmation_ask_me_later">Ask later</string>
48+
<string name="setting_confirmation_yes">Yes</string>
49+
<string name="setting_confirmation_no">No</string>
50+
4651
</resources>

core/res/res/values/tr_styles.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,8 @@
8585
<item name="windowEnterAnimation">@anim/translucent_enter</item>
8686
<item name="windowExitAnimation">@anim/translucent_exit</item>
8787
</style>
88+
89+
<style name="Widget.GifView" parent="@android:style/Widget">
90+
</style>
91+
8892
</resources>

core/res/res/values/tr_symbols.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,13 @@
115115
<java-symbol type="integer" name="config_uiThemeMode" />
116116
<java-symbol type="string" name="theme_auto_switch_mode_error" />
117117

118+
<!--Setting confirmation dialog-->
119+
<java-symbol type="style" name="Widget.GifView" />
120+
<java-symbol type="id" name="setting_confirmation_dialog_visual_hint" />
121+
<java-symbol type="id" name="setting_confirmation_dialog_visual_gif" />
122+
<java-symbol type="layout" name="setting_confirmation_dialog" />
123+
<java-symbol type="string" name="setting_confirmation_ask_me_later" />
124+
<java-symbol type="string" name="setting_confirmation_yes" />
125+
<java-symbol type="string" name="setting_confirmation_no" />
126+
118127
</resources>

packages/SystemUI/res/values/styles.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<item name="android:windowAnimationStyle">@style/Animation.RecentsActivity</item>
2121
</style>
2222

23-
<style name="RecentsTheme" parent="@android:style/Theme.Material.Wallpaper">
2423
<style name="RecentsTheme" parent="@android:style/Theme.DeviceDefault">
2524
<!-- NoTitle -->
2625
<item name="android:windowNoTitle">true</item>

0 commit comments

Comments
 (0)