fix:
update:更换为酷信
This commit is contained in:
2023-10-11 19:19:52 +08:00
parent 625a121cbb
commit 8799e85443
723 changed files with 4158 additions and 4041 deletions

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2018 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.uiuipad.os.testcomponent;
import android.appwidget.AppWidgetProvider;
/**
* A simple app widget without any configuration screen and is hidden in picker.
*/
public class AppWidgetHidden extends AppWidgetProvider { }

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
import android.appwidget.AppWidgetProvider;
/**
* A simple app widget without any configuration screen.
*/
public class AppWidgetNoConfig extends AppWidgetProvider {
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
/**
* A simple app widget with configuration sceen.
*/
public class AppWidgetWithConfig extends AppWidgetNoConfig {
}

View File

@@ -0,0 +1,128 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Base activity with utility methods to help automate testing.
*/
public class BaseTestingActivity extends Activity implements View.OnClickListener {
public static final String SUFFIX_COMMAND = "-command";
public static final String EXTRA_METHOD = "method";
public static final String EXTRA_PARAM = "param_";
private static final int MARGIN_DP = 20;
private final String mAction = this.getClass().getName();
private LinearLayout mView;
private int mMargin;
private final BroadcastReceiver mCommandReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleCommand(intent);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mMargin = Math.round(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, MARGIN_DP, getResources().getDisplayMetrics()));
mView = new LinearLayout(this);
mView.setPadding(mMargin, mMargin, mMargin, mMargin);
mView.setOrientation(LinearLayout.VERTICAL);
mView.setBackgroundColor(Color.BLUE);
setContentView(mView);
registerReceiver(mCommandReceiver, new IntentFilter(mAction + SUFFIX_COMMAND));
}
protected void addButton(String title, String method) {
Button button = new Button(this);
button.setText(title);
button.setTag(method);
button.setOnClickListener(this);
LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
lp.bottomMargin = mMargin;
mView.addView(button, lp);
}
@Override
protected void onResume() {
super.onResume();
sendBroadcast(new Intent(mAction).putExtra(Intent.EXTRA_INTENT, getIntent()));
}
@Override
protected void onDestroy() {
unregisterReceiver(mCommandReceiver);
super.onDestroy();
}
@Override
public void onClick(View view) {
handleCommand(new Intent().putExtra(EXTRA_METHOD, (String) view.getTag()));
}
private void handleCommand(Intent cmd) {
String methodName = cmd.getStringExtra(EXTRA_METHOD);
try {
Method method = null;
for (Method m : this.getClass().getDeclaredMethods()) {
if (methodName.equals(m.getName()) &&
!Modifier.isStatic(m.getModifiers()) &&
Modifier.isPublic(m.getModifiers())) {
method = m;
break;
}
}
Object[] args = new Object[method.getParameterTypes().length];
Bundle extras = cmd.getExtras();
for (int i = 0; i < args.length; i++) {
args[i] = extras.get(EXTRA_PARAM + i);
}
method.invoke(this, args);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Intent getCommandIntent(Class<?> clazz, String method) {
return new Intent(clazz.getName() + SUFFIX_COMMAND)
.putExtra(EXTRA_METHOD, method);
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
import android.annotation.TargetApi;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.ComponentName;
import android.content.IntentSender;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.widget.RemoteViews;
/**
* Sample activity to request pinning an item.
*/
@TargetApi(26)
public class RequestPinItemActivity extends BaseTestingActivity {
private PendingIntent mCallback = null;
private String mShortcutId = "test-id";
private int mRemoteViewColor = Color.TRANSPARENT;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addButton("Pin Shortcut", "pinShortcut");
addButton("Pin Widget without config ", "pinWidgetNoConfig");
addButton("Pin Widget with config", "pinWidgetWithConfig");
}
public void setCallback(PendingIntent callback) {
mCallback = callback;
}
public void setRemoteViewColor(int color) {
mRemoteViewColor = color;
}
public void setShortcutId(String id) {
mShortcutId = id;
}
public void pinShortcut() {
ShortcutManager sm = getSystemService(ShortcutManager.class);
// Generate icon
int r = sm.getIconMaxWidth() / 2;
Bitmap icon = Bitmap.createBitmap(r * 2, r * 2, Bitmap.Config.ARGB_8888);
Paint p = new Paint();
p.setColor(Color.RED);
new Canvas(icon).drawCircle(r, r, r, p);
ShortcutInfo info = new ShortcutInfo.Builder(this, mShortcutId)
.setIntent(getPackageManager().getLaunchIntentForPackage(getPackageName()))
.setIcon(Icon.createWithBitmap(icon))
.setShortLabel("Test shortcut")
.build();
IntentSender callback = mCallback == null ? null : mCallback.getIntentSender();
sm.requestPinShortcut(info, callback);
}
public void pinWidgetNoConfig() {
requestWidget(new ComponentName(this, AppWidgetNoConfig.class));
}
public void pinWidgetWithConfig() {
requestWidget(new ComponentName(this, AppWidgetWithConfig.class));
}
private void requestWidget(ComponentName cn) {
Bundle extras = null;
if (mRemoteViewColor != Color.TRANSPARENT) {
int layoutId = getResources().getIdentifier(
"test_layout_appwidget_view", "layout", getPackageName());
RemoteViews views = new RemoteViews(getPackageName(), layoutId);
views.setInt(android.R.id.icon, "setBackgroundColor", mRemoteViewColor);
extras = new Bundle();
extras.putParcelable(AppWidgetManager.EXTRA_APPWIDGET_PREVIEW, views);
}
AppWidgetManager.getInstance(this).requestPinAppWidget(cn, extras, mCallback);
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2018 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.uiuipad.os.testcomponent;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.DONT_KILL_APP;
import static android.os.ParcelFileDescriptor.MODE_READ_WRITE;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.util.Base64;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import androidx.test.InstrumentationRegistry;
/**
* Content provider to receive commands from tests
*/
public class TestCommandReceiver extends ContentProvider {
public static final String ENABLE_TEST_LAUNCHER = "enable-test-launcher";
public static final String DISABLE_TEST_LAUNCHER = "disable-test-launcher";
public static final String KILL_PROCESS = "kill-process";
@Override
public boolean onCreate() {
return true;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public Uri insert(Uri uri, ContentValues values) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
throw new UnsupportedOperationException("unimplemented mock method");
}
@Override
public Bundle call(String method, String arg, Bundle extras) {
switch (method) {
case ENABLE_TEST_LAUNCHER: {
getContext().getPackageManager().setComponentEnabledSetting(
new ComponentName(getContext(), TestLauncherActivity.class),
COMPONENT_ENABLED_STATE_ENABLED, DONT_KILL_APP);
return null;
}
case DISABLE_TEST_LAUNCHER: {
getContext().getPackageManager().setComponentEnabledSetting(
new ComponentName(getContext(), TestLauncherActivity.class),
COMPONENT_ENABLED_STATE_DISABLED, DONT_KILL_APP);
return null;
}
case KILL_PROCESS: {
((ActivityManager) getContext().getSystemService(Activity.ACTIVITY_SERVICE)).
killBackgroundProcesses(arg);
return null;
}
}
return super.call(method, arg, extras);
}
public static Bundle callCommand(String command) {
return callCommand(command, null);
}
public static Bundle callCommand(String command, String arg) {
Instrumentation inst = InstrumentationRegistry.getInstrumentation();
Uri uri = Uri.parse("content://" + inst.getContext().getPackageName() + ".commands");
return inst.getTargetContext().getContentResolver().call(uri, command, arg, null);
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
String path = Base64.encodeToString(uri.getPath().getBytes(),
Base64.NO_CLOSE | Base64.NO_PADDING | Base64.NO_WRAP);
File file = new File(getContext().getCacheDir(), path);
if (!file.exists()) {
// Create an empty file so that we can pass its descriptor
try {
file.createNewFile();
} catch (IOException e) { }
}
return ParcelFileDescriptor.open(file, MODE_READ_WRITE);
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2018 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.uiuipad.os.testcomponent;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_LAUNCHER;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
import android.app.LauncherActivity;
import android.content.Intent;
public class TestLauncherActivity extends LauncherActivity {
@Override
protected Intent getTargetIntent() {
return new Intent(ACTION_MAIN, null)
.addCategory(CATEGORY_LAUNCHER)
.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
}
}

View File

@@ -0,0 +1,275 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
import android.graphics.Point;
import android.util.Pair;
import android.view.InputDevice;
import android.view.MotionEvent;
import android.view.MotionEvent.PointerCoords;
import android.view.MotionEvent.PointerProperties;
import java.util.HashMap;
import java.util.Map;
/**
* Utility class to generate MotionEvent event sequences for testing touch gesture detectors.
*/
public class TouchEventGenerator {
/**
* Amount of time between two generated events.
*/
private static final long TIME_INCREMENT_MS = 20L;
/**
* Id of the fake device generating the events.
*/
private static final int DEVICE_ID = 2104;
/**
* The fingers currently present on the emulated touch screen.
*/
private Map<Integer, Point> mFingers;
/**
* Initial event time for the current sequence.
*/
private long mInitialTime;
/**
* Time of the last generated event.
*/
private long mLastEventTime;
/**
* Time of the next event.
*/
private long mTime;
/**
* Receives the generated events.
*/
public interface Listener {
/**
* Called when an event was generated.
*/
void onTouchEvent(MotionEvent event);
}
private final Listener mListener;
public TouchEventGenerator(Listener listener) {
mListener = listener;
mFingers = new HashMap<Integer, Point>();
}
/**
* Adds a finger on the touchscreen.
*/
public TouchEventGenerator put(int id, int x, int y, long ms) {
checkFingerExistence(id, false);
boolean isInitialDown = mFingers.isEmpty();
mFingers.put(id, new Point(x, y));
int action;
if (isInitialDown) {
action = MotionEvent.ACTION_DOWN;
} else {
action = MotionEvent.ACTION_POINTER_DOWN;
// Set the id of the changed pointer.
action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
}
generateEvent(action, ms);
return this;
}
/**
* Adds a finger on the touchscreen after advancing default time interval.
*/
public TouchEventGenerator put(int id, int x, int y) {
return put(id, x, y, TIME_INCREMENT_MS);
}
/**
* Adjusts the position of a finger for an upcoming move event.
*
* @see #move(long ms)
*/
public TouchEventGenerator position(int id, int x, int y) {
checkFingerExistence(id, true);
mFingers.get(id).set(x, y);
return this;
}
/**
* Commits the finger position changes of {@link #position(int, int, int)} by generating a move
* event.
*
* @see #position(int, int, int)
*/
public TouchEventGenerator move(long ms) {
generateEvent(MotionEvent.ACTION_MOVE, ms);
return this;
}
/**
* Commits the finger position changes of {@link #position(int, int, int)} by generating a move
* event after advancing the default time interval.
*
* @see #position(int, int, int)
*/
public TouchEventGenerator move() {
return move(TIME_INCREMENT_MS);
}
/**
* Moves a single finger on the touchscreen.
*/
public TouchEventGenerator move(int id, int x, int y, long ms) {
return position(id, x, y).move(ms);
}
/**
* Moves a single finger on the touchscreen after advancing default time interval.
*/
public TouchEventGenerator move(int id, int x, int y) {
return move(id, x, y, TIME_INCREMENT_MS);
}
/**
* Removes an existing finger from the touchscreen.
*/
public TouchEventGenerator lift(int id, long ms) {
checkFingerExistence(id, true);
boolean isFinalUp = mFingers.size() == 1;
int action;
if (isFinalUp) {
action = MotionEvent.ACTION_UP;
} else {
action = MotionEvent.ACTION_POINTER_UP;
// Set the id of the changed pointer.
action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
}
generateEvent(action, ms);
mFingers.remove(id);
return this;
}
/**
* Removes a finger from the touchscreen.
*/
public TouchEventGenerator lift(int id, int x, int y, long ms) {
checkFingerExistence(id, true);
mFingers.get(id).set(x, y);
return lift(id, ms);
}
/**
* Removes an existing finger from the touchscreen after advancing default time interval.
*/
public TouchEventGenerator lift(int id) {
return lift(id, TIME_INCREMENT_MS);
}
/**
* Cancels an ongoing sequence.
*/
public TouchEventGenerator cancel(long ms) {
generateEvent(MotionEvent.ACTION_CANCEL, ms);
mFingers.clear();
return this;
}
/**
* Cancels an ongoing sequence.
*/
public TouchEventGenerator cancel() {
return cancel(TIME_INCREMENT_MS);
}
private void checkFingerExistence(int id, boolean shouldExist) {
if (shouldExist != mFingers.containsKey(id)) {
throw new IllegalArgumentException(
shouldExist ? "Finger does not exist" : "Finger already exists");
}
}
private void generateEvent(int action, long ms) {
mTime = mLastEventTime + ms;
Pair<PointerProperties[], PointerCoords[]> state = getFingerState();
MotionEvent event = MotionEvent.obtain(
mInitialTime,
mTime,
action,
state.first.length,
state.first,
state.second,
0 /* metaState */,
0 /* buttonState */,
1.0f /* xPrecision */,
1.0f /* yPrecision */,
DEVICE_ID,
0 /* edgeFlags */,
InputDevice.SOURCE_TOUCHSCREEN,
0 /* flags */);
mListener.onTouchEvent(event);
if (action == MotionEvent.ACTION_UP) {
resetTime();
}
event.recycle();
mLastEventTime = mTime;
}
/**
* Returns the description of the fingers' state expected by MotionEvent.
*/
private Pair<PointerProperties[], PointerCoords[]> getFingerState() {
int nFingers = mFingers.size();
PointerProperties[] properties = new PointerProperties[nFingers];
PointerCoords[] coordinates = new PointerCoords[nFingers];
int index = 0;
for (Map.Entry<Integer, Point> entry : mFingers.entrySet()) {
int id = entry.getKey();
Point location = entry.getValue();
PointerProperties property = new PointerProperties();
property.id = id;
property.toolType = MotionEvent.TOOL_TYPE_FINGER;
properties[index] = property;
PointerCoords coordinate = new PointerCoords();
coordinate.x = location.x;
coordinate.y = location.y;
coordinate.pressure = 1.0f;
coordinates[index] = coordinate;
index++;
}
return new Pair<MotionEvent.PointerProperties[], MotionEvent.PointerCoords[]>(
properties, coordinates);
}
/**
* Resets the time references for a new sequence.
*/
private void resetTime() {
mInitialTime = 0L;
mLastEventTime = -1L;
mTime = 0L;
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright (C) 2017 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.uiuipad.os.testcomponent;
import android.os.Bundle;
/**
* Simple activity for widget configuration
*/
public class WidgetConfigActivity extends BaseTestingActivity {
public static final String SUFFIX_FINISH = "-finish";
public static final String EXTRA_CODE = "code";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addButton("Cancel", "clickCancel");
addButton("OK", "clickOK");
}
public void clickCancel() {
setResult(RESULT_CANCELED);
finish();
}
public void clickOK() {
setResult(RESULT_OK);
finish();
}
}